递归合并排序功能给出错误的输出

时间:2015-09-21 05:17:25

标签: c++ sorting recursion merge mergesort

我试图找出为什么我的合并排序功能不起作用。我相信问题在merge()部分内。这是我的代码:

int mergeSort(int *data, int left, int right) {
    //divide
    if (left < right) {
        int q = floor((left + right) / 2);
        //conquer
        mergeSort(data, left, q);
        mergeSort(data, q + 1, right);
        //combine
        merge(data, left, q, right);
    }

    //print results for testing purposes
    for (int i = 0; i < n; i++) {
        cout << data[i] << "\n";
    }

    return 0;
}

这是merge()的一部分。我相信问题就在这一部分内。

int merge(int *data, int left, int q, int right) {
    int *temp = data;
    int i = left, j = q + 1, z = left;
    int t1 = 0, t2 = 0;
    while (i <= q && j <= right) { //while both variables have not reached the end of their sub arrays
        if (temp[i] <= temp[j]) {
            data[z] = temp[i];
            i++;
        }
        else {
            data[z] = temp[j];
            j++;
        }
        z++;
    }
     //if subarrays are both sorted and in order, combine them
    if (i < q) {
        t1 = z, t2 = i;
        for (t1; t1 < right;) {
            data[t1] = temp[t2];
            t1++;
            t2++;
        }
    }

    else if (j < right) {
        int t1 = z; int t2 = j;
        for (t1; t1 <= right;) {
            data[t1] = temp[t2];
            t1++;
            t2++;
        }
    } 

我认为我的问题来自于int *temp = data;开头宣布merge()。我的想法是,我在这两个数组之间遇到某种内存地址冲突,但我不确定。

我已经尝试以不同的顺序排列数据,并且发现当需要将数据从索引n移动到索引n-i时,这两个索引之间的每个索引都被替换为n的值。例如:

传递数组{4, 13, 8, 12, 9 }将返回{4, 8, 8, 9, 9}

我的另一个想法是i和j变量没有正确递增。我反复考虑过这段代码,似乎无法找到解决方案。

1 个答案:

答案 0 :(得分:1)

这(merge函数的第一行)

int *temp = data;

复制数组;它只是创建指向同一内存的另一个指针。这会导致您的代码覆盖您的数据。

你可能需要这样做:

int * temp = new int [right - left + 1];
memcpy (temp, data + left, (right - left + 1) * sizeof(int));

并且在功能结束时忘记delete[] temp的记忆:

delete[] temp;

请注意,您需要更改z的使用情况;它应该从0开始,而不是从left开始。

(以下是可选的性能改进;您可以忽略它们。) 在每个merge函数中分配和释放内存是个坏主意。特别是因为我们确切地知道合并需要多少额外内存:一组精确的n整数。

出于这个原因,最好将另一个相同大小的数组与data一起传递给mergeSort,这样它就可以用作临时存储器(即临时存储器)合并。或者,如果你真的很聪明,你可以在实际和临时内存之间乒乓,以尽量减少复制。