用C编写无指针的合并排序

用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

我试图用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 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];