合并排序错误的输出

时间:2013-10-18 04:31:28

标签: c++ sorting

我正在尝试使用以下合并排序函数对数组进行排序。然而,它没有给我预期的输出。 它不会打印出正确/预期的输出,即

输入:5,4,3,2,1
产出:1,2,3,4,5

相反,它给出:2,3,4,5,1,9,8,7,8,4,1,8,8,2。

#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>

using namespace std;

void mergeSort(int a[], int low , int high,int res[]);
void merge(int a[], int low , int mid , int high,int res[]);
void mergeSort(int numbers[], int temp[], int array_size);

const int SIZE=5;

int main () {

    int sorted[SIZE];
    for (int i=0; i<SIZE; i++) {
        cout << "input numbers" <<endl;
        cin >>sorted[i];
    }
    int merge[SIZE];

    mergeSort(sorted,merge,SIZE);

    for (int i=0; i<SIZE; i++) {
        cout << merge[i];
    }

    return 0;
}

void mergeSort(int numbers[], int temp[], int array_size)
{
    mergeSort(numbers, 0, array_size-1, temp);
}

void mergeSort(int a[], int low , int high,int res[])
{
    int mid = (low + high)  /2;
    if (low + 1 < high)
    {
        //  Sort sub-parts
        mergeSort(a,low,mid,res);
        mergeSort(a,mid,high,res);

        //  Merge back to "res"
        merge(a,low,mid,high,res);
    }else{
        res[low] = a[low];
    }
}

void merge(int a[], int low , int mid , int high,int res[])
{
    int i = low;
    int j = mid;
    int k = low;   //  Use "low" instead of 0.

    while (i < mid && j < high)
        if(a[i] < a[j])
            res[k++] = a[i++];
        else
            res[k++] = a[j++];

    while (i < mid)
        res[k++] = a[i++];

    while (j < high)
        res[k++] =a[j++];

    //  Copy back to "a"
    for (int c = low; c < high; c++){
        a[c] = res[c];
    }
}

3 个答案:

答案 0 :(得分:3)

我认为这导致了问题 -

    //  Sort sub-parts
    mergeSort(a,low,mid,res);
    mergeSort(a,mid,high,res);

应该是

    //  Sort sub-parts
    mergeSort(a,low,mid,res);
    mergeSort(a,mid+1,high,res);

同样if (low + 1 < high)应更改为if (low < high)

此外while (i < mid && j < high)应为while (i <= mid && j <= high),单个while循环也需要使用&lt; =

进行更新

答案 1 :(得分:1)

您对索引限制的处理存在一些混淆。

表示范围的两种常用方法是:

  1. 范围限制指向元素
  2. 范围限制指向元素
  3. range coordinate systems

    在图片中,上面的编号使用“指向元素”方法,灰色范围为(2, 5)

    下面的编号是使用“指向元素”的方法,相同的范围是(2, 4)

    作为个人喜好,我更喜欢“元素之间”方法:例如,范围的大小为high-low,您可以轻松地表示空范围甚至倒置范围。但重要的是,如果您在编写管理范围的代码时使用第一种或第二种方法,那么您总是要清醒。

    在你的代码中存在那种混乱;例如,在mergesort中,您正在检查是否

    low + 1 < high
    

    这意味着您正在使用“元素之间”方法,因为当high - low = 1表示只有一个元素且不需要排序时。此外,您还可以递归传递(low, mid)(mid, high):另一个明确的信号是使用“元素之间”方法,因为您肯定不想两次移动array[mid]

    在相同的代码中,您将在主程序中传递函数0array_size-1,这是一个明确的信号,在这种情况下,您将使用“指向元素”方法。

    只需仔细检查所有索引和范围用法是否一致,代码就可以了。

答案 2 :(得分:0)

根据您的示例代码,结果只打印5个数字(因为 const int SIZE = 5 )。

除此之外,请注意您将列表的最后一个元素的位置设置为“高”参数。

但是,在您的合并功能中,您的 while(j&lt; high)条件会确保列表中的最后一个元素不会被排序,因为排序会在到达之前停止。

更新:需要调整合并函数末尾的for循环,以便将最后一个(“高”)元素复制回数组 a