MergeSort递归实现C语言代码运行异常,求帮忙排查调试
归并排序代码错误点梳理
- 核心错误1:
helper函数直接覆盖原数组前缀,导致右半区数据丢失
调用mergeSort(helper(input,0,m),m)处理完左半区后,接下来调用helper(input,m,size)时,会将原数组m到size位置的元素复制到input数组的前size-m位,直接覆盖了刚处理好的左半区数据,后续merge的时候已经没有正确的左半区内容可以合并。 - 核心错误2:
merge函数忽略start参数,写入位置错误
merge逻辑最后把合并好的临时数组内容从input[0]开始写入,完全没有用到传入的start参数。如果是对原数组的非前缀子段进行归并,会直接覆盖其他段已经排好序的内容。 - 其他问题:
helper里的局部变长数组a在C语言中属于栈上分配,递归层级深时容易栈溢出,且频繁复制数组会大幅降低排序效率。
修正思路
不需要用helper函数拆分复制数组,直接给mergeSort传入数组的起始、结束索引,在原数组上操作即可,以下是修正后的参考代码:
void merge(int input[], int start, int mid, int end) { int len = end - start; int temp[len]; int i = start, j = mid, k = 0; while (i < mid && j < end) { temp[k++] = input[i] < input[j] ? input[i++] : input[j++]; } while (i < mid) temp[k++] = input[i++]; while (j < end) temp[k++] = input[j++]; for (int p = 0; p < len; p++) { input[start + p] = temp[p]; } } void mergeSort(int input[], int start, int end) { if (end - start <= 1) return; int mid = start + (end - start) / 2; mergeSort(input, start, mid); mergeSort(input, mid, end); merge(input, start, mid, end); } // 对外调用入口 void mergeSortEntry(int input[], int size) { mergeSort(input, 0, size); }
内容的提问来源于stack exchange,提问作者Frtug
相关产品推荐
相关产品推荐

