【发布时间】:2021-07-11 19:54:23
【问题描述】:
我试图解决一个问题,该问题要求编写归并排序代码,但不使用额外的数组来对初始数组进行分区。我想写的代码几乎是好的,但我面临的问题是我无法弄清楚如何在排序时维护和更新数组。我知道问题出在合并功能上。
如何修复代码?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void PrintArray(int A[], int n)
{
for(int i=0; i < n; i++)
printf("%d ", A[i]);
printf("\n");
}
void merge(int A[], int left, int mid, int right, int n){
int B[n];
int i = left, j = mid+1, k=0;
while(i<=mid && j <= right){
if(A[i]>=A[j]){
B[k++] = A[i++];
}
else {
B[k++] = A[j++];
}
}
while(i<=mid){
B[k++] = A[i++];
}
while(j<=right){
B[k++] = A[j++];
}
for(i=0; i<n; i++){
A[i] = B[i];
}
}
void MergeSort(int A[], int left, int right, int n)
{
if(left<right){
int mid;
mid = floor((left+right)/2);
MergeSort(A,left,mid,n/2);
MergeSort(A,mid+1,right,n/2);
merge(A,left,mid,right,n);
}
else return;
}
int main()
{
int n;
scanf("%d",&n);
int A[n];
for(int i=0; i < n; i++) scanf("%d", &A[i]);
MergeSort(A, 0, n-1, n);
PrintArray(A, n);
return 0;
}
【问题讨论】:
-
en.wikipedia.org/wiki/Merge_sort 仅使用两个数组(源和目标)提供一堆算法。或者您正在寻找就地算法?
-
您希望如何在单个数组中“分区”任何内容?如果将数组大小加倍并使用偏移量,则可以,但这与正确使用单独的数组进行分区没有什么不同。
-
@DavidC.Rankin 我想我们不需要真正对数组进行分区。我们可以使用变量 left、right 和 mid 对它进行虚拟分区,因为我们可以通过将第一个数组从左到中限制,然后将另一个从 mid+1 到右,虚拟地创建两个数组。
-
@EugeneSh。我认为使用单个额外数组作为临时存储进行排序,然后将其复制回初始数组将被视为就地算法,但正如 Craig 提到的那样,这种方法有时会导致堆栈溢出,并不是真正的就地方法,所以我想我的方法不准确。但是我这样尝试是因为问题特别指出我们不能创建 2 个额外的数组来进行分区并提供了一个代码结构来填充这就是为什么我们甚至不能像 Wikipedia 解决方案那样创建更多函数
-
@SuryanshManav 你有多个数组。您在
main()中声明了VLAA,在merge()中声明了B。并且由于您从MergeSort()递归调用merge(),因此您在每个递归级别创建了 3 个以上的 VLA。到最后,您可能已经使用了几十个数组。
标签: arrays c sorting mergesort