我尝试修改合并排序以存储原始索引后修改它没有正确排序..我无法找到我出错的地方请帮我找到问题..
请在下面找到我的代码。
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]);
}
答案 0 :(得分:2)
您的基本问题在于合并算法的初始while循环:
if(L[i] < R[j])
这是比较两个int [2]数组的内存地址,而不是相同的第二个插槽中保存的值,这就是你应该做的事情。
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