我在合并排序代码中获取垃圾值

时间:2019-02-13 20:18:06

标签: c++ mergesort

我正在尝试在C ++中实现合并排序算法。这是我的代码。逻辑似乎很好。 但是我得到的输出是垃圾值,我无法弄清代码中的问题所在。 我认为我的逻辑是正确的,但我不确定。

#include <iostream>
using namespace std;
void Merge(int A[],int L[],int nL,int R[],int nR);
void MergeSort(int A[]);

   //Function to Merge Arrays L and R into A. 
   //nL = number of elements in L
   //nR = number of elements in R. 
void Merge(int A[],int L[],int nL,int R[],int nR)
{ 
   // i - to mark the index of left subarray (L)
   // j - to mark the index of right sub-raay (R)
   // k - to mark the index of merged subarray (A)
   int i=0;
   int j=0;
   int k=0;
  while(i<nL && j<nR)
   {
      if(L[i]<=R[i])
      { A[k]=L[i];
        i=i+1;
      }
      else
      { A[k]=R[j];
        j=j+1;
      }
      k=k+1;
  }
  while(i<nL)
  { A[k]=L[i];
      i=i+1;
      k=k+1;
  }
  while(j<nR)
  { A[k]=R[j];
    j=j+1;
    k=k+1;
  }
}
// Recursive function to sort an array of integers. 
void MergeSort(int A[],int n)
{
  if (n<2) return;//base condition.If the array has less than two 
                     //elements, do nothing
  int mid=n/2;
   // create left and right subarrays
   // mid elements (from index 0 till mid-1) should be part of left sub- 
      //array 
   // and (n-mid) elements (from mid to n-1) will be part of right sub- 
      //array
  int left[mid];
  int right[n-mid];

  for(int i=0;i<mid-1;i++) left[i]=A[i];// create left subarray
  for(int i=mid;i<n-1;i++) right[i-mid]=A[i];// create right subarray

  MergeSort(left,mid);
  MergeSort(right,n-mid);
  Merge(A,left,mid,right,n-mid);
}

int main()
{ int A[]={2,4,7,1,5,3};
  int n=sizeof(A)/sizeof(A[0]);
  MergeSort(A,n);
  for(int i=0;i<n;i++) cout<<A[i]<<" ";

  return 0;
}

预期输出为1 2 3 4 5 7

但是实际是0 -785903160 1 0(每次都不一样)

2 个答案:

答案 0 :(得分:0)

对此问题的回答是how-to-implement-classic-sorting-algorithms-in-modern-c。但是我想我会发布一个答案,对初学者来说我觉得很有价值,因为我过去多次看到这个问题。这一定是一个受欢迎的家庭作业问题。

我认为,如果这是现代的C ++赋值,则应该减少使用索引的次数。

因此在此实现中,我没有使用std :: merge并编写了合并,因此可以看到一些方法

避免使用成语:using namespace std;为什么被教给我。使用Typedef定义您的类型,这一点要清楚得多。

using data_vect = std::vector<int>;

希望这已经足够清楚了,并且完全可以通过迭代器完成。它效率不高,可以避免合并中的push_back。我是DuckDucked这类人,最初的几首歌曲并不是那么好。

#include <iostream>
#include <vector>

using data_vect = std::vector<int>;
using dv_iter = data_vect::iterator;

data_vect Merge(data_vect& first, data_vect& second)
{
    data_vect result;
    dv_iter fval = first.begin();
    dv_iter sval = second.begin();
    for (;fval != first.end() || sval != second.end();)
    {
        if (fval == first.end())
            result.push_back(*sval++);
        else if (sval == second.end())
            result.push_back(*fval++);
        else if (*fval < *sval)
            result.push_back(*fval++);
        else
            result.push_back(*sval++);
    }
    return result;
}

void MergeSort(data_vect& input)
{
    int half = input.size() / 2;
    if (! half)
        return;

    data_vect left(input.begin(), input.begin() + half );
    data_vect right(input.begin() + half, input.end());

    MergeSort(left);
    MergeSort(right);
    input = Merge(left, right);
}

int main()
{
    data_vect A = { 6,2,7,4,1,5,3 };
    MergeSort(A);
    for ( auto& val : A )
        std::cout << val << " ";

    return 0;
}

答案 1 :(得分:-2)

虽然可以理解, 在C ++中无法声明具有可变大小的数组,例如int[mSize]。 所有数组必须具有恒定的大小,例如int[10]

const int mSize = 10;
int[mSize] mArray...

您想要一个大小可变的存储容器。正如@PaulMcKenzie所建议的, 您可能要使用Vector对象。您的代码如下所示:

#include <iostream>
#include <vector>

using namespace std;
void Merge(vector<int>& A, vector<int>& L, vector<int>& R);
void MergeSort(vector<int>& A);

   //Function to Merge Arrays L and R into A. 
void Merge(vector<int>& A, vector<int>& L, vector<int>& R)
{ 
   // i - to mark the index of left subarray (L)
   // j - to mark the index of right sub-raay (R)
   // k - to mark the index of merged subarray (A)
   unsigned int i=0;
   unsigned int j=0;
   unsigned int k=0;
  while(i<L.size() && j<R.size())
   {
      if(L[i]<=R[i])
      { A[k]=L[i];
        i=i+1;
      }
      else
      { A[k]=R[j];
        j=j+1;
      }
      k=k+1;
  }
  while(i<L.size())
  { A[k]=L[i];
      i=i+1;
      k=k+1;
  }
  while(j<R.size())
  { A[k]=R[j];
    j=j+1;
    k=k+1;
  }
}
// Recursive function to sort an array of integers. 
void MergeSort(vector<int>& A)
{
  int n = A.size();
  if (n<2) return;//base condition.If the array has less than two 
                     //elements, do nothing
  int mid=n/2;
   // create left and right subarrays
   // mid elements (from index 0 till mid-1) should be part of left sub- 
      //array 
   // and (n-mid) elements (from mid to n-1) will be part of right sub- 
      //array
  vector<int> left(mid);
  vector<int> right(n-mid);

  for(int i=0;i<mid;i++) left[i]=A[i];// create left subarray
  for(int i=mid;i<n;i++) right[i-mid]=A[i];// create right subarray

  MergeSort(left);
  MergeSort(right);
  Merge(A,left,right);
}

int main()
{ vector<int> A={2,4,7,1,5,3};
  MergeSort(A);
  for(unsigned int i=0;i<A.size();i++) cout<<A[i]<<" ";

  return 0;
}

[编辑] 我注意到我不小心在vector.size()调用中使用了逗号而不是点。另外,我注意到2个数组在复制左右向量时过早停止了一项。

您的代码无效。上面的代码可以很好地编译,但是会生成1 3 5 2 4 7作为输出。另外,您是否想到过长度不均匀的向量,例如5 4 3 2 1

目前,代码无法正确分割