【问题标题】:Merge-Sort Algorithm. Merge function does not work合并排序算法。合并功能不起作用
【发布时间】:2016-05-09 16:59:55
【问题描述】:

我正在尝试执行合并排序算法,但遇到了带有合并功能的块。我尝试了几种不同的方法来尝试解决这个问题,并遵循了几个 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
}

【问题讨论】:

  • 帮助读者:一个合并函数通常需要两个数组作为输入,它们不一定是相同的大小,所以不清楚你的单数组和单长度如何取@987654325 @ 函数应该可以工作。此外,你在这个函数中做的第一件事就是计算size = (length - startIndex) + 1,所以length 并不是我想的那样。
  • 对不起。我应该更好地澄清这一点。我有一个实验室,作为实验室的一部分,我得到了两个函数签名;我必须在不更改签名的情况下实现功能。我已经看到传递了两个数组的方法以及传递了低、中、高的方法,但我不能使用它。长度变量有点令人困惑,我同意,但我得到了它,我无法修改它。

标签: c++ algorithm sorting merge mergesort


【解决方案1】:

看起来你的错误在这里

    }
    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);

【讨论】:

猜你喜欢
  • 2020-12-05
  • 2016-08-19
  • 1970-01-01
  • 2013-08-04
  • 2018-12-04
  • 2015-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多