对未排序的向量进行合并排序

Posted

技术标签:

【中文标题】对未排序的向量进行合并排序【英文标题】:Mergesort on Vectors not sorting 【发布时间】:2016-03-31 19:36:50 【问题描述】:

我正在尝试对向量进行合并排序,但我不知道我的错误是什么。我已经进行了桌面测试,它工作正常,但是当我运行代码时,它不知道为什么它没有对任何东西进行排序并用 thrash 填充向量。

代码如下:

#include<iostream>
#include<vector>

using namespace std;


//los vectores se pasan por referencia
void merge(vector<int>& v, int inicio, int medio, int fin)
  int primera_mitad = medio-inicio+1; //para el primer arreglo
  int segunda_mitad = fin-medio;      //para el segundo arreglo
  //copio a cada arreglo las mitades
  vector<int> n1;
  vector<int> n2;
  int i,j,k;
  for(i=0; i<primera_mitad; i++)
    n1.push_back(v[inicio+i]);
  
  for(j = 0; j<segunda_mitad; j++)
    n2.push_back(v[medio+j+1]);
  
  //Ahora realizo las comparaciones para volver a ingresar al vector completo los valores
  //de las mitades en orden.
  i=0;
  j=0;
  k=inicio;
  while(i<n1.size() && j<n2.size()) //Mientras hayan elementos por pasar en ambos subarreglos(subvector)
    if(n1[i]<=n2[j])
        v.insert(v.begin()+k, n1[i]);
        i++;
    
    else
      v.insert(v.begin()+k, n2[j]);
      j++;
    
    k++;
  
  //Puede darse el caso de que un subarreglo se vacíe mas rápido que otro, por lo que pasamos directamente
  //los demás elementos
  while(i<n1.size())
    v.insert(v.begin()+k, n1[i]);
    i++;
    k++;
  
  while(j<n2.size())
    v.insert(v.begin()+k, n2[j]);
    j++;
    k++;
  


void merge_sort(vector<int>& v, int inicio, int fin)
  if(inicio<fin)
    int medio = ((fin+inicio)/2);
    merge_sort(v, inicio, medio);
    merge_sort(v, medio+1, fin);
    merge(v, inicio, medio, fin);
  



void print(vector<int>& v)
  cout<<endl;
  int tam = v.size();
  for(int i = 0; i<tam; i++)
    cout<<i+1<<".\t"<<v[i]<<"\n";
  


int main() 
  cout<<"----------------MERGE SORT----------------\n\n";
  cout<<"\nPlease, fill the vector: \n\n";
  int a;
  bool response = true;
  vector<int> v;
  while(response)
      cout<<"\nEnter your number: ";
      cin>>a;
      v.push_back(a);
      cout<<"Another?(1/0): ";
      cin>>response;
      cout<<endl;
  
  int tam = v.size();
  merge_sort(v, 0, tam-1);
  print(v);
  return 0;

例如,当我将此数字作为输入时:

1 4 10 5 6

程序给了我这个输出:

1.  1
2.  1
3.  1
4.  10
5.  10
6.  1
7.  1
8.  10
9.  1
10. 10
11. 1
12. 10
13. 1
14. 10
15. 4
16. 5
17. 6

希望你能帮助我。谢谢。

【问题讨论】:

欢迎来到 Stack Overflow!听起来您可能需要学习如何使用调试器来逐步执行代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。延伸阅读:How to debug small programs 你的程序失败了,只有两个数字,更不用说 5 个数字了。例如,如果输入是2 1,您会看到输出不是1 2。所以你有一些基本错误,即使是最小的输入。 看起来您正在从 n1 和 n2 向 v 添加值,而没有先从 v 中删除。 【参考方案1】:

不要从一开始就从列表中复制,只需跟踪您所在的位置并合并到新的输出列表中即可。完成后,用新值替换旧值。不要使用 v.insert()。 v[idx] = 输出[idx2]

您可以保留两个输入列表,但仍需要替换列表中的值。 v[idx++] = 值。 idx 需要从第一个列表的开头开始。

在任何一种情况下,您都可以考虑使用迭代器而不是索引。这样您就可以避免传递向量。您不需要随机访问结构来编写合并排序。它应该与 std::list 一起使用。可以使用++iter遍历元素。

【讨论】:

那么,v.insert() 不会替换已经在我想要放置新号码的位置上的号码? @CarlosAbelCórdova 不,它在您指定的位置插入一个新数字(假设它在目标向量的有效迭代器范围内)。

以上是关于对未排序的向量进行合并排序的主要内容,如果未能解决你的问题,请参考以下文章

使用向量进行合并排序 (int) C++

将两个排序向量合并到一个排序向量中

C++ 合并和排序 2 个向量

合并排序的合并操作不使用 C++ 向量

合并 K 个排序数组/向量的复杂性

向量下标超出范围 C++ 合并排序