合并排序算法。合并功能不起作用

时间:2016-05-09 16:59:55

标签: c++ algorithm sorting merge mergesort

我正在尝试进行Merge-Sort算法,但是我遇到了一个带有merge函数的块。我已经尝试了几种不同的方法来尝试解决这个问题并遵循了几个YouTube教程,但它仍然不起作用。

有人可以帮我弄清楚这有什么问题吗?

归并

void mergeSort(int arrayToSort[], int startIndex, int lengthToSort) {

    int midIndex = 0;

    if (startIndex < lengthToSort) { // if base case not reached
        int midIndex = (startIndex + lengthToSort) / 2;
        mergeSort(arrayToSort, startIndex, midIndex);
        mergeSort(arrayToSort, (midIndex + 1), lengthToSort);
        merge(arrayToSort, startIndex, lengthToSort);
    }
}

合并

void merge(int arraySortedInTwoHalves[], int startIndex, int length) {

    int size = (length - startIndex) + 1;
    int padding = 0;

    if (size % 2 > 0) (padding = 1);

    int *temp = new int[size];

    int left = size / 2;
    int right = (size / 2) + padding;

    int i = 0;
    int j = (size / 2) + padding;
    int k = 0;

    while ((i < left) && (j < length)) {

        if (arraySortedInTwoHalves[i] <= arraySortedInTwoHalves[j]) {
            temp[k] = arraySortedInTwoHalves[i];
            i++;
        }
        else {
            temp[k] = arraySortedInTwoHalves[j];
            j++;
        }
        k++;
        while (i < left) {
            temp[k] = arraySortedInTwoHalves[i];
            k++;
        }
        while (j < length) {
            temp[k] = arraySortedInTwoHalves[j];
            j++;
        }
    }
}

主要

int main() {

    // setup an array of random numbers of size n
    const int arrSize = 50;
    int nums[arrSize];

    for (int i = 0; i <= arrSize; i++) {
        nums[i] = rand() % arrSize;
    }

    mergeSort(nums, 0, arrSize-1);

    for (int i = 0; i < arrSize; i++) {
        std::cout << nums[i] << " ";
    }

    return(0);
}

解决方案

这是我制作的完整解决方案,以防万一对其他人有帮助......

#include <iostream>
#include <random>
#include <ctime>

void mergeSort(int arrayToSort[], int startIndex, int lengthToSort);
void merge(int arraySortedInTwoHalves[], int startIndex, int length);

int main() {

    // setup an array of random numbers of size n
    const int arrSize = 10000;
    int nums[arrSize];

    for (int i = 0; i <= arrSize; i++) {
        nums[i] = rand() % arrSize;
    }

    // just a timer to measure performance
    int start_s = clock();

    mergeSort(nums, 0, arrSize-1);

    for (int i = 0; i < arrSize; i++) {
        std::cout << nums[i] << " ";
    }

    // stop timer
    int stop_s = clock();
    std::cout << std::endl << std::endl << "Executed In: " << (stop_s - start_s) / double(CLOCKS_PER_SEC) << "s\n" << std::endl;

    system("pause");
    return(0);
}

void mergeSort(int arrayToSort[], int startIndex, int lengthToSort) {

    int midIndex = 0;

    if (startIndex < lengthToSort) { // if base case not reached
        midIndex = (startIndex + lengthToSort) / 2;
        mergeSort(arrayToSort, startIndex, midIndex);
        mergeSort(arrayToSort, (midIndex + 1), lengthToSort);
        merge(arrayToSort, startIndex, lengthToSort);
    }
}

void merge(int arraySortedInTwoHalves[], int startIndex, int length) {

    int size = (length - startIndex) + 1;
    int *temp = new int[size]; // temp array to hold elements

    int left = startIndex; // left side of the array
    int midIndex = (startIndex + length) / 2; // border
    int right = midIndex + 1; // right side of the array
    int i = 0;

    while ((left <= midIndex) && (right <= length)) { // while there are elements in both sides...

        if (arraySortedInTwoHalves[left] < arraySortedInTwoHalves[right]) { // add whichever is lower from the appropriate side
            temp[i++] = arraySortedInTwoHalves[left++];
        }
        else {
            temp[i++] = arraySortedInTwoHalves[right++];
        }
    }
    while (left <= midIndex) // if one runs out... 
    {
        temp[i++] = arraySortedInTwoHalves[left++];
    }
    while (right <= length) // if one runs out... 
    {
        temp[i++] = arraySortedInTwoHalves[right++];
    }

    for (i = 0; i < size; i++) { // copy elements to the original array
        arraySortedInTwoHalves[startIndex + i] = temp[i]; // startIndex + i because of recursion
    }
    delete []temp; // delete temp array
}

1 个答案:

答案 0 :(得分:0)

看起来你的错误就在这里

    }
    k++;
    while (i < left) {
        temp[k] = arraySortedInTwoHalves[i];
        k++;
    }
    while (j < length) {
        temp[k] = arraySortedInTwoHalves[j];
        j++;
    }
}

这应该是

    }
    k++;
} //  Moved brace from end to here.

// These two loops should be after the main loop.

while (i < left) {
    temp[k] = arraySortedInTwoHalves[i];
    // You forgot to increment i
    k++;
}
while (j < length) {
    temp[k] = arraySortedInTwoHalves[j];
    j++;
    // You forgot to increment k
}

很难判断是否存在其他错误,但我怀疑此处还有更多错误。

使用此处的长度(lengthToSort)。

void mergeSort(int arrayToSort[], int startIndex, int lengthToSort) {

arrayToSort + lengthToSort是一个结束的点。这种情况表明您使用的是标准C ++惯用语[begin,end)

下一个电话似乎遵循该惯例。

        mergeSort(arrayToSort, startIndex, midIndex);

但是这个电话似乎表明长度是包容性的。当你从范围中排除midIndex时(这意味着它应该在上面的调用中)。但这意味着lengthToSort也应该在下面的范围内,但这不是原始呼叫的含义。

        mergeSort(arrayToSort, (midIndex + 1), lengthToSort);

你的范围是否正确?为了帮助明确这一点,很多实现都通过使用接口来实现这一点。

        mergeSort(begin, mid);  // begin, mid and end are iterators.
        mergeSort(mid, end);
        merge(begin, mid, end);