我正在尝试在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(每次都不一样)
答案 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
?
目前,代码无法正确分割