求助:无法排查C++归并排序代码错误
归并排序Merge函数排错指南
哥们,我太懂这种盯着调试器几小时找不到bug的崩溃感了!咱们来揪出你这段merge代码里的问题:
首先先把你贴的代码片段补全(应该是粘贴时没写完),方便分析:
void merge(int lo, int mid, int hi) { T* aux = new T[(hi - lo) + 1]; int i = lo; int j = mid + 1; for (int k = 0; k <= (hi - lo); k++) { if (i > mid) { aux[k] = arrayData[j]; j++; // 这里你应该是没写完,补全j++ } // 其他分支的逻辑你应该也漏了 } // 这里缺了关键步骤! }
核心问题&修复方案
我一眼就看到几个致命问题:
- 没把合并后的aux数组写回原数组:你只是把元素合并到了aux里,但原数组
arrayData完全没被更新!这就是排序没效果的根本原因。 - 分支逻辑不完整:你只处理了
i > mid(左子数组遍历完)的情况,没处理右子数组遍历完、以及左右元素比较的分支,这会导致aux数组填充不完整。 - 可能的笔误:
j+...肯定是j++的笔误,不然编译都通不过。 - 内存泄漏风险:你用
new创建了aux数组,但没delete[]释放内存。
给你修正后的完整merge函数:
void merge(int lo, int mid, int hi) { T* aux = new T[(hi - lo) + 1]; int i = lo; int j = mid + 1; // 合并左右子数组到aux for (int k = 0; k <= (hi - lo); k++) { if (i > mid) { // 左子数组已遍历完,取右子数组元素 aux[k] = arrayData[j++]; } else if (j > hi) { // 右子数组已遍历完,取左子数组元素 aux[k] = arrayData[i++]; } else if (arrayData[i] <= arrayData[j]) { // 左元素更小,取左 aux[k] = arrayData[i++]; } else { // 右元素更小,取右 aux[k] = arrayData[j++]; } } // 关键!把aux的合并结果写回原数组的对应位置 for (int k = lo; k <= hi; k++) { arrayData[k] = aux[k - lo]; // 注意aux的索引和原数组的偏移关系 } // 释放内存,避免泄漏 delete[] aux; }
调试小技巧
如果你还是不确定哪里出问题,可以加几行打印代码,直观看到每个步骤的数组内容:
// 填充完aux后打印 cout << "Merge [" << lo << "," << mid << "] and [" << mid+1 << "," << hi << "]" << endl; cout << "aux array: "; for (int k=0; k<=hi-lo; k++) cout << aux[k] << " "; cout << endl; // 写回原数组后打印对应区间 cout << "arrayData after merge: "; for (int k=lo; k<=hi; k++) cout << arrayData[k] << " "; cout << endl;
这样就能清楚看到是aux合并错了,还是没写回原数组,一目了然。
内容的提问来源于stack exchange,提问作者Wolfun1t
相关产品推荐
相关产品推荐

