用C编写无指针的合并排序
我试图用C语言编写家庭作业代码,将用户输入的10个整数放入一个数组,并使用递归合并排序对其进行排序。我们还没有讨论过指针,所以我想避免在代码中使用指针(许多在线示例都使用指针) 这是我的密码:用C编写无指针的合并排序,c,function,recursion,mergesort,C,Function,Recursion,Mergesort,我试图用C语言编写家庭作业代码,将用户输入的10个整数放入一个数组,并使用递归合并排序对其进行排序。我们还没有讨论过指针,所以我想避免在代码中使用指针(许多在线示例都使用指针) 这是我的密码: /* This code will take input for 10 integers given by the user into an array, sort them with a recursive merge function and print the updated array in as
/* This code will take input for 10 integers given by the user
into an array, sort them with a recursive merge function
and print the updated array in ascending order. */
#include <stdio.h>
#define ARRSIZE 10
void merge_sort (int arr[], int temp[], int left, int right);
void merge (int arr[], int temp[], int left, int mid, int right);
int main (void){
int arr[ARRSIZE], temp[ARRSIZE], left, right, i;
printf("Enter 10 integers for an array:");
for(i=0;i<ARRSIZE;i++){
printf("\narray value %d:", i+1);
scanf("%d", &arr[i]);
}
left = 0;
right = ARRSIZE-1;
merge_sort(arr, temp, left, right);
printf("\nHere is your updated array:");
printf("\n{");
for(i=0;i<ARRSIZE;i++){
printf("%d,", arr[i]);
}
printf("}");
return 0;
}
void merge_sort (int arr[], int temp[], int left, int right){
if(left<right){
int mid = (right-left)/2;
merge_sort(arr, temp, left, mid);
merge_sort(arr, temp, mid+1, right);
merge(arr, temp, left, mid, right);
}
}
void merge (int arr[], int temp[], int left, int mid, int right){
int i, j, tempi = 0;
for(i=left, j=mid+1; i<=mid && j<=right ;){
// mid+1 is the start of the right array
if(arr[i]<arr[j] && i<=mid){
temp[tempi] = arr[i];
tempi++;
i++;
}
else if(arr[i]>arr[j] && j<=right){
temp[tempi] = arr[j];
tempi++;
j++;
}
}
for(i=0,j=right; i<=j; i++){
arr[i] = temp[i];
}
}
/*此代码将接受用户给定的10个整数的输入
在数组中,使用递归合并函数对它们进行排序
并按升序打印更新后的数组*/
#包括
#定义尺寸10
无效合并排序(int arr[],int temp[],int left,int right);
无效合并(int arr[],int temp[],int left,int mid,int right);
内部主(空){
int arr[ARRSIZE],temp[ARRSIZE],左,右,i;
printf(“为数组输入10个整数:”);
对于(i=0;i我已经发现了一个微妙的错误:intmid=(右左)/2;
应该是intmid=(左+右)/2;
此外,我还发现了哪些流程:
为了简单起见,您应该使用tempi=left
。只需将数组的传入部分复制到临时数组的相应部分
在合并周期中,您可以将递增的tempi放入中,用于定义:
对于(…;…;++tempi)
在该循环中,您在从该位置读取值后检查边界。这非常糟糕。非常糟糕。尽管如此,您在这里没有遇到任何问题,只是因为您正在检查中的边界以获取定义:)只需删除它们:
for (i = left, j = 1 + mid; i <= mid && j <= right; ++tempi)
{
if (arr[i] < arr[j]) temp[tempi] = arr[i++];
else /* arr[j] <= arr[i] */ temp[tempi] = arr[j++];
}
用于(i=left,j=1+mid;i在哪一行是seg fault?我的shell没有告诉我,我输入了a.out,它就运行了。但是我知道错误在我的merge或merge_sort函数的某个地方。即使在调试版本中?使用gcc-o merge sort-g merge sort.c编译,然后在gdb:gdb./merge sortbtw下运行,从技术上讲,当您传递arr时我试图找出是否有一条线导致我的索引超出了数组的边界。我找到了另一种改进合并的方法:当主for循环完成时,我们可以有两种情况:1.我们结束了左子数组。2.我们结束了子数组。在第一种情况下,我们将在上,我们不需要将元素复制到j
右侧的temp
,然后再返回到arr
。只要if(i>mid)right=tempi;
我们就完成了。对right
变量的更改是局部的,可以优化我们的许多工作:)等等,“if(i>mid)right=tempi;”代替行“if”(i>mid)i=j;'?这会影响(;tempi-yup)的“是”。它会影响该行和最后一行(从temp复制回arr)。如果您现在还不能理解,请尝试理解第一个解决方案。是的,我开始理解您的第一个解决方案。所有的第一个更改只是缩短并简化了我的代码。然后您使用下一个for循环将剩余的arr值添加到temp。所以设置tempi=right只会跳过第二个for循环?
if (i > mid) i = j; /* if we need to copy right subarray */
for (; tempi <= right; ++tempi, ++i) temp[tempi] = arr[i];
for (i = left; i <= right; ++i) arr[i] = temp[i];