c - 修改合并排序以存储原始索引

标签 c sorting mergesort

<分区>

我尝试修改合并排序以存储原始索引,修改后排序不正确。我找不到哪里出错了请帮我找到问题。

请在下面找到我的代码。

void merge(int a[][2],int start,int middle ,int end)
{
    int size1 = middle-start +1;
    int size2 = end-middle;
    int i,j;
    int k =start;
    int L[size1][2];
    int R[size2][2];
    //int *L = (int *)malloc(sizeof(int)*size1);
    //int *R = (int *)malloc(sizeof(int)*size2);

    // copy values from main array to temp arrays
    for(i=0 ; i<size1; i++)
    {
        L[i][1] = a[i+start][1];
        L[i][0] = a[i+start][0];
    }
    for(j=0 ; j<size2 ; j++)
    {
        R[j][1] = a[j+middle+1][1];
        R[j][0] = a[j+middle+1][0];
    }

    i=0;
    j=0;
    while(i<size1 && j<size2)
    {
        if(L[i] < R[j])
        {
            a[k][1] = L[i][1];
            a[k][0] = L[i][0];
            k++;
            i++;
        }
        else{
            a[k][1] = R[j][1];
            a[k][0] = R[j][0];
            k++;
            j++;
        }
    }
    while(i<size1)
    {
        a[k][1] = L[i][1];
        a[k][0] = L[i][0];
        i++;
        k++;
    }
    while(j<size2)
    {
        a[k][1] = R[j][1];
        a[k][0] = R[j][0];
        k++;
        j++;
    }
}

void mergeSort(int a[][2], int start , int end)
{
    if(start < end)
    {
        int middle = start + (end - start) /2;
        mergeSort(a,start, middle);
        mergeSort(a,middle+1,end);
        merge(a,start,middle,end);
    }
}

int main()
{
    int array[10][2] = {{0,55},{1,3},{2,4},{3,5},{4,6},{5,7},{6,8},{7,9},{8,10},{9,2}};
    int i;
    int len = sizeof(array)/sizeof(array[0]) - 1;
    for(i = 0 ;i <= 9; i++)
        printf("%d",array[i][1]);
    mergeSort(array,0,9);
    printf ( "\nArray after sorting:\n") ;
    printf ( "\nindex after sorting:\n") ;
    for(i = 0 ;i <= 9; i++)
        printf("%d",array[i][0]);
    printf ( "\nArray after sorting:\n") ;
    for(i = 0 ;i <= 9; i++)
        printf("%d",array[i][1]);
}

最佳答案

您的根本问题在于合并算法的初始 while 循环:

if(L[i] < R[j])

这是比较两个 int[2] 数组的内存地址,而不是 said-same 的第二个槽中保存的值,这是你应该做的。

if(L[i][1] < R[j][1])

也就是说,这可以变得相当简单,但这是主要问题的症结所在。


指针数学版本

为了补充我在这个答案中留下的评论,以下是您的代码的简化版本,它使用指针数学来进行段拆分,而不仅仅是索引。仔细查看对 mergeSort() 的递归调用以及参数。还要注意在 merge 算法中使用单个临时数组和索引:

void merge(int a[][2], int mid, int len)
{
    int tmp[len][2];
    int i,j,k=0;

    // copy values from main array to temp
    memcpy(tmp, a, len*sizeof(*a));

    i=0; j=mid;
    while(i<mid && j<len)
    {
        if (tmp[i][1] < tmp[j][1])
        {
            // take from left side
            a[k][1] = tmp[i][1];
            a[k][0] = tmp[i++][0];
        }
        else
        {   // take from right side
            a[k][1] = tmp[j][1];
            a[k][0] = tmp[j++][0];
        }

        ++k; // always incremented
    }

    // one of these is skipped. the other will
    //  finish the merge algorithm
    while(i<mid)
    {
        a[k][1] = tmp[i][1];
        a[k++][0] = tmp[i++][0];
    }

    while(j<len)
    {
        a[k][1] = tmp[j][1];
        a[k++][0] = tmp[j++][0];
    }
}

void mergeSort(int a[][2], int len)
{
    if (len > 1)
    {
        int mid = len / 2;
        mergeSort(a, mid);
        mergeSort(a+mid, len-mid); // note: pointer math for right-segment
        merge(a, mid, len);
    }
}

int main()
{
    int array[10][2] = {{0,55},{1,3},{2,4},{3,5},{4,6},{5,7},{6,8},{7,9},{8,10},{9,2}};
    int i;
    int len = sizeof(array)/sizeof(array[0]);
    for(i = 0 ;i < len; i++)
        printf("%d ",array[i][1]);

    mergeSort(array, len);

    printf ( "\nIndex after sorting:\n") ;
    for(i = 0 ;i < len; i++)
        printf("%d ",array[i][0]);

    printf ( "\nArray after sorting:\n") ;
    for(i = 0 ;i < len; i++)
        printf("%d ",array[i][1]);
}

输出

55 3 4 5 6 7 8 9 10 2 
Index after sorting:
9 1 2 3 4 5 6 7 8 0 
Array after sorting:
2 3 4 5 6 7 8 9 10 55

关于c - 修改合并排序以存储原始索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21060934/

相关文章:

java - spark java中如何实现按值排序

java - Java中使用Queue进行归并排序

java - 合并两个数组时出错

C - 打印字符 '>'

c - 使用链接列表将文件中的单词读取到动态字符中

c - 有效的 C 代码在 Swift 项目中不起作用

ios - 如何基于数组快速对多个数组进行排序?

python - 如何查找具有平局数字的列表中的最大数字

c - 在帕特里夏/基数树上插入单词时遇到问题

python - 合并排序递归错误