C 朴素指针算术合并排序返回错误
试图使用指针算法实现一个简单的合并排序,但它返回的是无意义的结果。我遵循的惯例是,C 朴素指针算术合并排序返回错误,c,pointers,mergesort,C,Pointers,Mergesort,试图使用指针算法实现一个简单的合并排序,但它返回的是无意义的结果。我遵循的惯例是,l是最左边的有效索引,r是最右边的有效索引 输入是51324,但它返回:01025,预期输出自然是12345 #include <stdio.h> void mergeptr(int *array, int l, int m, int r) { int tmp[r - l + 1]; int *tptr = &(tmp[0]); int *lptr = &(ar
l
是最左边的有效索引,r
是最右边的有效索引
输入是51324
,但它返回:01025
,预期输出自然是12345
#include <stdio.h>
void mergeptr(int *array, int l, int m, int r)
{
int tmp[r - l + 1];
int *tptr = &(tmp[0]);
int *lptr = &(array[l]);
int *rptr = &(array[m]);
/* Find the smallest in each side */
while ((lptr < &array[m]) && (rptr < &array[r]))
if (*lptr <= *rptr) *tptr++ = *lptr++;
else *tptr++ = *rptr++;
/* Copy the remaining */
while (lptr < &array[m]) *tptr++ = *lptr++;
while (rptr < &array[r]) *tptr++ = *rptr++;
/* Copy back */
for (size_t i = 0; i < (r-l+1); ++i)
array[l+i] = tmp[i];
}
void merge_sort(int *array, int l, int r) {
if (l < r) {
int m = (l + r) / 2;
merge_sort(array, l, m);
merge_sort(array, m + 1, r);
mergeptr(array, l, m, r);
}
}
int main(void) {
int values[5] = { 5, 1, 3, 2, 4 };
merge_sort(&values[0], 0, 4);
for (size_t i = 0; i < 5; ++i)
printf("%d ", values[i]);
printf("\n");
return 0;
}
#包括
void mergeptr(int*数组、int l、int m、int r)
{
int tmp[r-l+1];
int*tptr=&(tmp[0]);
int*lptr=&(数组[l]);
int*rptr=&(数组[m]);
/*找出两边最小的*/
而((lptr<&array[m])和&(rptr<&array[r]))
如果(*lptr您在处理边界时应该小心。
您的merge\u sort
函数似乎正在处理范围[l,r)
(包括l
,不包括r
),因此:
- 不应执行元素
m
:merge\u sort(数组,m+1,r);
应merge\u sort(数组,m,r);
- 当只有1个元素时,不需要排序:
if(l
应该是if(l+1
mergeptr
函数中的r-l+1
和r-l+1
应为r-l
和r-l
固定代码:
#include <stdio.h>
void mergeptr(int *array, int l, int m, int r)
{
int tmp[r - l];
int *tptr = tmp;
int *lptr = array + l;
int *rptr = array + m;
/* Find the smallest in each side */
while( (lptr < (array + m)) && (rptr < (array + r)))
if( *lptr <= *rptr) *tptr++ = *lptr++;
else *tptr++ = *rptr++;
/* Copy the remaining */
while(lptr < (array + m)) *tptr++ = *lptr++;
while(rptr < (array + r)) *tptr++ = *rptr++;
/* Copy back */
for(size_t i = 0; i < (r-l); ++i)
array[l+i] = tmp[i];
}
void merge_sort(int *array, int l, int r) {
if (l + 1 < r) {
int m = (l+r)/2;
merge_sort(array, l, m);
merge_sort(array, m, r);
mergeptr(array, l, m, r);
}
}
int main(void) {
int values[5] = { 5, 1, 3, 2, 4 };
merge_sort(values, 0, 5);
for(size_t i = 0; i < 5; ++i)
printf("%d ", values[i]);
printf("\n");
return 0;
}
#包括
void mergeptr(int*数组、int l、int m、int r)
{
int-tmp[r-l];
int*tptr=tmp;
int*lptr=array+l;
int*rptr=array+m;
/*找出两边最小的*/
而((lptr<(数组+m))&&(rptr<(数组+r)))
if(*lptr)您是否尝试调试它?在函数中添加一些额外的printf以显示调试跟踪。这是使用lerning C“[32,52]”值(第34行)&array[r]的方法
未定义的行为对吗?我想你需要做一些更改吗?@SaiSreenivas根据5.7加法运算符,指针指向最后一个元素后一个应该是有效的。遗憾的是,许多教程和老师提倡将两个边界都包括在内的约定。这会导致代码繁琐且容易出错。Makingr
excluded允许使用更简单的代码,如图所示。