合并排序 - 输出错误

时间:2017-08-06 01:03:27

标签: c algorithm sorting merge mergesort

我刚刚在C中实现了Merge Sort。在逻辑方面,我认为我的代码是正确的。虽然,输出是错误的。并且输出不是原始数组中的数字。这就是我觉得奇怪的事情。请帮我。我收到的输出是:-1 0 0 -1 0 4。

以下是代码:

#include <stdio.h>
#include <stdlib.h>

void merge (int right[], int left[], int elements[], int midValue) {

    int lengthL = midValue; /*tamanho do array da esquerda*/
    int lengthR = midValue - 1; /*tamanho do array da direita*/

    int i = 0; /*index do numero mais pequeno no array da esquerda*/
    int j = 0; /*index do numero mais pequeno no array da direita*/
    int k = 0; /*representa o index da posicao que precisa de ser preenchida no array original
               que neste caso é "elementos"*/

    while (i < lengthL && j < lengthR) {
        if (left[i] <= right[j]) {
            elements[k] = left[i];
            i = i + 1;
        }
        else {
            elements[k] = right[j];
            j = j + 1;
        }
        k = k + 1;
    }


    /*estes dois while loops seguintes sao para as sobras em ambos
    os arrays. depois de sair do primeiro while loop que esta acima apenas um
    dos while loops a seguir serao executados pois apenas irá haver sobras em apenas um deles*/

    while (i < lengthL) {
        elements[k] = elements[i];
        i = i + 1;
        k = k + 1;
    }

    while (j < lengthR) {
        elements[k] = elements[j];
        j = j + 1;
        k = k + 1;
    }

}

void MergeSort (int elements[], int numberOfElements) {

    if (numberOfElements < 2) {
        return;
    }

    int midValue = numberOfElements / 2;

    int left[midValue];
    int right[midValue - 1];

    for (int i = 0; i < midValue - 1; i = i + 1) {
        left[i] = elements[i];
    }

    for (int i = midValue; i < numberOfElements - 1; i = i + 1) {
        right[i] = elements[i];
    }

    MergeSort(left, midValue);
    MergeSort(right, midValue - 1);
    merge(left, right, elements, midValue);
}



int main() {

    int elements[6] = {2, 1, 5, 3, 7, 4};

    int numberOfElements = 6; /*número de elementos do array*/

    MergeSort(elements, numberOfElements);

    for(int i = 0; i < numberOfElements; i = i + 1) {
        printf("%d ",elements[i]);
    }

}

1 个答案:

答案 0 :(得分:2)

您的代码中似乎存在多个错误。 例如,MergeSort的输入包含一个数组elements 元素编号为0,1,...,(numberOfElements - 1)。将这些元素从elements复制到leftright数组的循环不会复制元素编号(midValue - 1)(太大而无法由left循环复制,太小而无法被right循环复制)也不会复制元素编号(numberOfElements - 1)。

此外,MergeSort内的第二个循环将数据写入超出为right数组分配的空间末尾的某个位置,而不是right数组中的正确位置。 要正确复制elements的后半部分,应将elements的元素编号midValue复制到right的元素编号0。 你的代码显然没有这样做。

然而,当您将leftright数组传递到merge末尾附近的MergeSort时,merge会对left数组进行处理好像它包含midValue元素,即使它只包含(midValue - 1)元素。

我认为还有更多,但你已经做了很多调试。尝试打印出每个函数的输入和输出以查看函数是否正在执行您期望的操作,或尝试使用较小的测试用例(例如长度为2的数组)并在调试器中逐步执行时遵循程序的逻辑