我的合并排序没有正确排序

时间:2014-03-14 19:08:38

标签: c++ sorting merge

所以我已经分配了一个学校项目来实现教授给出的伪代码的合并排序。这是我想出来的,在我的用例中, 而不是订购:     0 1 4 5 9 它命令它:     5 4 1 0 9

我的用例:     5 9 1 0 5 4

这里是合并排序的合并部分和全局变量

long long intercambio;
int aux[5555], arr[555];

void merge(int begin, int middle, int end) {
    int i = begin, j = middle+1, k = begin, temp;
    while (i <= middle && j <= end) {
        if (arr[i] < arr[j]) {
            aux[k] = arr[i];
            i++;
        }
        else {
            aux[k] = arr[j];
            j++;
        }
        k++;
        noSwaps++;
    }
    if (i > middle) {
        while (j <= end) {
            if (aux[k -1] > arr[j]) {
                temp = aux[k - 1];
                aux[k - 1] = arr[j];
                aux[k] = temp;
                noSwaps++;
            }
            else {
                aux[k] = arr[j];
            }
            k++;
            j++;
        }
    }
    else {
        while (i <= middle) {
            if (aux[k -1] > arr[i]) {
                temp = aux[k - 1];
                aux[k - 1] = arr[i];
                aux[k] = temp;
                noSwaps++;
            }
            else {
                aux[k] = arr[i];
            }
            k++;
            i++;
        }
    }
}

这里我递归地调用合并排序

void mergeSort(int begin, int end) {
    if (begin < end) {
        int middle = (begin + end) / 2;
        mergeSort(begin, middle);
        mergeSort(middle + 1, end);
        merge(begin, middle, end);
    }
}

这是主要的课程

int main(int argc, const char * argv[])
    {
        int len;

        cin >> len;
        while (len != 0) {

            for (int x = 0; x < len; x++)
                cin >> arr[x];

            noSwaps = 0;

            mergeSort(0, len - 1);
            for (int x = 0; x < len; x++)
                cout << aux[x] << " ";
            cout << endl;

            cout << noSwaps << endl;

            cin >> len;
        }

        return 0;
    }

1 个答案:

答案 0 :(得分:0)

我不明白为什么if (i > middle)块及其else块内的代码如此复杂。您所要做的就是将剩余的元素复制到aux,然后从aux复制回arr

void merge(int begin, int middle, int end) {
    int i = begin, j = middle+1, k = begin, temp;
    while (i <= middle && j <= end) {
        // ... same as before ...
    }
    while (i <= middle)
    {
        aux[k++] = arr[i++];
    }
    while (j <= end)
    {
        aux[k++] = arr[j++];
    }
    for (i = begin; i <= end; ++i)
    {
        arr[i] = aux[i];
    }
}

这可能会或可能不会比您的解决方案更低(或更高),但至少它有效:)

顺便说一句,有一个可爱的技巧来实现合并排序,你不必担心在另一个范围之前耗尽一个范围。您将左侧范围按升序复制到aux,将右侧范围按降序复制。然后开始从两端合并,当索引满足时,两个范围都用尽了:

void merge(int begin, int middle, int end)
{
    int i, j, k;
    for (i = begin; i <= middle; ++i)
    {
        aux[i] = arr[i];
    }
    for (j = end; j > middle; --j, ++i)
    {
        aux[i] = arr[j];
    }
    i = begin;
    j = end;
    k = begin;
    while (i <= j)
    {
        arr[k++] = aux[(aux[i] < aux[j]) ? i++ : j--];
    }
}

此解决方案似乎产生了错误的输出,但仅仅是因为main中存在错误:

for (int x = 0; x < len; x++)
    cout << aux[x] << " ";

您正在打印aux,实际上您应该打印arr

for (int x = 0; x < len; x++)
    cout << arr[x] << " ";