大家好我需要使用给定的headerSort()标头在C ++中编写合并排序;
我的分区是正确的,但是它合并了一个在它有0之前合并的数组。例如:如果我有[34] [21]我得到[21,34]但是当它与let' s说[8]合并时它给出[0,0,8]。我正在失去价值观。请帮我调试一下。
int * merge(int * left ,int szLeft ,int * right,int szRight, int &compCount, int &moveCount){
int * newArr = new int [szLeft+szRight];
cout << "Left: ";
for (int i = 0; i < szLeft; ++i){
cout << left[i] << " ";
}
cout << endl;
cout << "Right: ";
for (int i = 0; i < szRight; ++i){
cout << right[i] << " ";
}
cout << endl;
int bigArrIndex = 0, rightArrIndex = 0,leftArrIndex = 0;
while(leftArrIndex < szLeft && rightArrIndex < szRight){
compCount++;
if(right[rightArrIndex] <= left[leftArrIndex]){
newArr[bigArrIndex] = right[rightArrIndex];
rightArrIndex++;
compCount++;
}
else{
newArr[bigArrIndex] = left[leftArrIndex];
leftArrIndex++;
}
moveCount++;
bigArrIndex++;
}
//1 more computation done even if the loop is not executed
compCount++;
//copy the rest of the stuff if left
while(rightArrIndex < szRight){
moveCount++;
compCount++;
newArr[bigArrIndex] = right[rightArrIndex];
rightArrIndex++;
bigArrIndex++;
}
//1 more computation done even if the loop is not executed
compCount++;
//copy the rest of the stuff if left
while(leftArrIndex < szLeft){
moveCount++;
compCount++;
newArr[bigArrIndex] = left[leftArrIndex];
leftArrIndex++;
bigArrIndex++;
}
//1 more computation done even if the loop is not executed
compCount++;
return newArr;
}
void mergeSort( int * arr, int size, int &compCount, int &moveCount){
//to take the branch or not needs 1 comparison
compCount++;
if(size > 1){
int mid = size/2;
int * left = new int[mid];
int * right = new int[size-mid];
for(int i = 0; i < mid; i++){
compCount++;
left[i] = arr[i];
moveCount++;
}
//1 more computation done even if the loop is not executed
compCount++;
for(int i = mid; i < size; i++){
right[i-mid] = arr[i];
moveCount++;
compCount++;
}
//1 more computation done even if the loop is not executed
compCount++;
mergeSort(left,mid,compCount,moveCount);
mergeSort(right,size-mid,compCount,moveCount);
int * sortedArr = merge(left,mid,right,size-mid,compCount,moveCount);
cout << "Done: ";
for (int i = 0; i < size; ++i)
cout << sortedArr[i] << " ";
cout << endl;
//delete[] left;
//delete[] right;
for(int i = 0; i < size; i++){
arr[i] = sortedArr[size];
moveCount++;
compCount++;
}
//1 more computation done even if the loop is not executed
compCount++;
}
}
答案 0 :(得分:0)
只需一行。注释中注明了修复:
//delete[] left;
//delete[] right;
for(int i = 0; i < size; i++){
arr[i] = sortedArr[i]; // fix from [size] to [i]
moveCount++;
compCount++;
}
注释:在mergeSort中,不是左右分配,代码可以使用arr而不是left,而arr + mid而不是right。减少两次分配。一个入口/辅助函数可以一次分配与原始数组大小相同的临时数组,并将其作为参数传递给mergeSort(),而mergeSort()又将它作为参数传递给merge()。在这种情况下,所有mergeSort都会在堆栈上创建索引对,并且merge会执行实际的合并并复制回来。
虽然可能超出了这个类的范围,但也可以使用mergeSort的两个相互递归版本来消除副本,其中一个是合并数据在原始数组中结束,调用此mergeSortO(),其中一个是合并数据最终在temp数组中,调用此mergeSortT()。 mergeSortO()调用mergeSortT()两次(左右两半),然后调用merge()从temp数组合并到原始数组。 mergeSortT()调用mergeSortO()两次(左右两半),然后调用merge()从原始数组合并到临时数组,或者如果size为1,则将一个元素从原始数组复制到临时数组。
也可能超出了类,另一种选择是自下而上合并排序,因为大多数库如STL std :: stable_sort()使用自下而上合并排序的一些变体。