我正在尝试使用以下合并排序函数对数组进行排序。然而,它没有给我预期的输出。 它不会打印出正确/预期的输出,即
输入: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];
}
}
答案 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)
您对索引限制的处理存在一些混淆。
表示范围的两种常用方法是:
在图片中,上面的编号使用“指向元素”方法,灰色范围为(2, 5)
。
下面的编号是使用“指向元素”的方法,相同的范围是(2, 4)
。
作为个人喜好,我更喜欢“元素之间”方法:例如,范围的大小为high-low
,您可以轻松地表示空范围甚至倒置范围。但重要的是,如果您在编写管理范围的代码时使用第一种或第二种方法,那么您总是要清醒。
在你的代码中存在那种混乱;例如,在mergesort
中,您正在检查是否
low + 1 < high
这意味着您正在使用“元素之间”方法,因为当high - low = 1
表示只有一个元素且不需要排序时。此外,您还可以递归传递(low, mid)
和(mid, high)
:另一个明确的信号是使用“元素之间”方法,因为您肯定不想两次移动array[mid]
。
在相同的代码中,您将在主程序中传递函数0
和array_size-1
,这是一个明确的信号,在这种情况下,您将使用“指向元素”方法。
只需仔细检查所有索引和范围用法是否一致,代码就可以了。
答案 2 :(得分:0)
根据您的示例代码,结果只打印5个数字(因为 const int SIZE = 5 )。
除此之外,请注意您将列表的最后一个元素的位置设置为“高”参数。
但是,在您的合并功能中,您的 while(j&lt; high)条件会确保列表中的最后一个元素不会被排序,因为排序会在到达之前停止。
更新:需要调整合并函数末尾的for循环,以便将最后一个(“高”)元素复制回数组 a 。