归并排序C实现
我按照归并排序算法在 Xcode 上用 C 语言编写了这段代码。 问题是有时我会收到 EXC_BAD_ACCESS 并且无法管理错误所在! 合并算法应该可以工作(我在合并排序函数之外尝试过并且可以工作!)。感谢您的帮助和耐心!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIM 6
void mymerge (int v[], int i1,int i2, int last); //mergesort core: merge two ordinated arrays in one bigger ordinated array
void mymergesort (int v[], int lower, int upper);//mergesort
void printv (int v[],int lower, int upper);
int main () {
int i;
srand((unsigned int)time(NULL));
int v[DIM];
for (i=0; i<DIM; i++)
v[i]=rand()%15;
printv(v, 0, DIM-1);
getc(stdin);
mymergesort(v, 0, DIM-1);
printv(v, 0, DIM-1);
}
void printv (int v[],int lower, int upper){
int i;
for (i=lower; i<=upper; i++)
printf("%d\t",v[i]);
}
void mymergesort (int v[], int lower, int upper){
int mid=(upper+lower)/2;
if (upper<lower) {
mymergesort(v, lower, mid);
mymergesort(v, mid+1, upper);
mymerge(v,lower,mid+1,upper);
}
}
void mymerge (int v[], int i1,int i2, int last){
int i=i1,j=i2,k=i1,*vout;
vout=(int*)malloc((last-i1+1)*sizeof(int));
while (i<i2 && j<=last) {
if (v[i]<=v[j]) {
vout[k++]=v[i++];
}else {
vout[k++]=v[j++];
}
}
for (;i<i2;i++) vout[k++]=v[i];
for (;j<=last;j++) vout[k++]=v[j];
for (k=i1; k<=last; k++) v[k]=vout[k];
free(vout);
}
编辑: 非常感谢!但我认为还有另一个问题,当我尝试对更大的数组(200 个元素)进行排序时,程序不起作用(我收到 malloc 错误:已释放对象的校验和不正确 - 对象可能在释放后被修改)。但如果我从 xCode 调试器运行它,一切正常
i wrote this code in C language on Xcode following the algorithm of mergesort.
The problem is that sometimes i get EXC_BAD_ACCESS and i can't manage where the error is!
The merge algorithm should work (i tried it outside the mergesort function and works!). Thank you for your help and patience!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DIM 6
void mymerge (int v[], int i1,int i2, int last); //mergesort core: merge two ordinated arrays in one bigger ordinated array
void mymergesort (int v[], int lower, int upper);//mergesort
void printv (int v[],int lower, int upper);
int main () {
int i;
srand((unsigned int)time(NULL));
int v[DIM];
for (i=0; i<DIM; i++)
v[i]=rand()%15;
printv(v, 0, DIM-1);
getc(stdin);
mymergesort(v, 0, DIM-1);
printv(v, 0, DIM-1);
}
void printv (int v[],int lower, int upper){
int i;
for (i=lower; i<=upper; i++)
printf("%d\t",v[i]);
}
void mymergesort (int v[], int lower, int upper){
int mid=(upper+lower)/2;
if (upper<lower) {
mymergesort(v, lower, mid);
mymergesort(v, mid+1, upper);
mymerge(v,lower,mid+1,upper);
}
}
void mymerge (int v[], int i1,int i2, int last){
int i=i1,j=i2,k=i1,*vout;
vout=(int*)malloc((last-i1+1)*sizeof(int));
while (i<i2 && j<=last) {
if (v[i]<=v[j]) {
vout[k++]=v[i++];
}else {
vout[k++]=v[j++];
}
}
for (;i<i2;i++) vout[k++]=v[i];
for (;j<=last;j++) vout[k++]=v[j];
for (k=i1; k<=last; k++) v[k]=vout[k];
free(vout);
}
EDIT:
thank you very much! but i think think there is another problem, when I try to sort a bigger array (200 elements), the program doesn't work (i get a malloc error: incorrect checksum for freed object - object was probably modified after being freed). But if I run it from the xCode debugger everything works fine
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这个:
vout=(int*)malloc((last-i1)*sizeof(int));
是错误的。首先,您想要的元素数量是
last-i1+1
,而不是last-i1
- 经典的 off-by-1。这种错误是 C 代码中的约定是使下限包含在内而上限不包含的原因之一 - 需要减少+1
和-1
,搞砸的机会更少。更严重的错误是您从
i1
开始索引vout
。如果您这样做,则需要为vout
分配last+1
元素,并且您永远不会使用第一个i1
(索引 0 . .i1-1
)。修复:首先,分配
last-i1+1
元素。其次,一开始将k
初始化为0,而不是i1
。第三,将最终副本更改为This:
vout=(int*)malloc((last-i1)*sizeof(int));
is wrong.First, the number of elements you want is
last-i1+1
, notlast-i1
- classic off-by-1. This kind of error is one of the reasons why the convention in C code is to make lower bounds inclusive and upper bounds exclusive - less+1
and-1
you need to do, less opportunity to screw up.The more serious error is that you index
vout
starting fromi1
. If you do it this way, you need to allocatelast+1
element forvout
, and you never use the firsti1
(index 0 ..i1-1
).Fix: First, allocate
last-i1+1
elements. Second, initializek
to 0 at the beginning, noti1
. Third, change the final copy to be你有两个问题。首先,您对中点的计算不正确 - 您使用
(upper - lower)/ 2
,但这不能保证位于lower
和upper 之间
。您真正想要的是lower + (upper - lower) / 2
。如果要排序的区间中只有 1 个数字,也无需执行任何操作 - 因此mymergesort()
函数应如下所示:第二个问题是
mymerge( )
函数已经由 Fabian Giesen 指出。You have two problems. The first is that your calculation of the midpoint is incorrect - you use
(upper - lower)/ 2
, but this is not guaranteed to lie betweenlower
andupper
. What you actually want islower + (upper - lower) / 2
. It's also not necessary to do any work if there's only 1 number in the interval to be sorted - so themymergesort()
function should look like:The second problem is the one in the
mymerge()
function already pointed out by Fabian Giesen.