Quicksort算法给出分段错误错误

时间:2017-06-03 11:26:07

标签: c algorithm sorting segmentation-fault quicksort

我正在尝试创建一个带有5个元素的向量的程序,并根据它们的距离对它们进行排序(“距离”意味着除了这里的点之外)。

但每次执行时它都会给我“分段错误”错误:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct 
{
char ID[8];
char Content[4];
int distance;

} DATA;


void sort(DATA *z, int l){

DATA p; //pivot
DATA t;
int aux=(l-1); //pivot's position
int i,j;

p.distance=z[l-1].distance;


if(l==1){return;}

for(i=0; i<l; i++){

    if((z[i].distance)<(p.distance)){

        continue;
    }


    if((z[i].distance)>(p.distance)){

        t=z[i];

            for(j=i; j<aux; j++){

                z[j]=z[j+1];

            }

            z[aux]=t;
            aux--;
    }

}


sort(z,aux-1);
sort(&z[aux+1],l-aux);

}

int main(){

DATA *z;
int l=5;
int i;

z=(DATA*)malloc(5*sizeof(DATA));

z[0].distance=5;
z[1].distance=1;
z[2].distance=4;
z[3].distance=3;
z[4].distance=2;

sort(z,l);

for(i=0; i<5; i++){

    printf("%d\n",z[i].distance);
}

free(z);

}

我看不出问题出在哪里。如果可以,请帮忙。

3 个答案:

答案 0 :(得分:0)

您在不检查第二个参数的值是什么的情况下递归调用sort。 用gdb执行代码产生了这个输出:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400661 in sort (z=0x602010, l=-513) at main.c:21
21  p.distance=z[l-1].distance;
(gdb) bt
#0  0x0000000000400661 in sort (z=0x602010, l=-513) at main.c:21
#1  0x000000000040077c in sort (z=0x602010, l=-511) at main.c:51
#2  0x000000000040077c in sort (z=0x602010, l=-509) at main.c:51
#3  0x000000000040077c in sort (z=0x602010, l=-507) at main.c:51
#4  0x000000000040077c in sort (z=0x602010, l=-505) at main.c:51
#5  0x000000000040077c in sort (z=0x602010, l=-503) at main.c:51
#6  0x000000000040077c in sort (z=0x602010, l=-501) at main.c:51
#7  0x000000000040077c in sort (z=0x602010, l=-499) at main.c:51
#8  0x000000000040077c in sort (z=0x602010, l=-497) at main.c:51
#9  0x000000000040077c in sort (z=0x602010, l=-495) at main.c:51
#10 0x000000000040077c in sort (z=0x602010, l=-493) at main.c:51
#11 0x000000000040077c in sort (z=0x602010, l=-491) at main.c:51
#12 0x000000000040077c in sort (z=0x602010, l=-489) at main.c:51
#13 0x000000000040077c in sort (z=0x602010, l=-487) at main.c:51
#14 0x000000000040077c in sort (z=0x602010, l=-485) at main.c:51
#15 0x000000000040077c in sort (z=0x602010, l=-483) at main.c:51
#16 0x000000000040077c in sort (z=0x602010, l=-481) at main.c:51
#17 0x000000000040077c in sort (z=0x602010, l=-479) at main.c:51
#18 0x000000000040077c in sort (z=0x602010, l=-477) at main.c:51
#19 0x000000000040077c in sort (z=0x602010, l=-475) at main.c:51
#20 0x000000000040077c in sort (z=0x602010, l=-473) at main.c:51
#21 0x000000000040077c in sort (z=0x602010, l=-471) at main.c:51
#22 0x000000000040077c in sort (z=0x602010, l=-469) at main.c:51

您可以使用调试符号编译代码,例如gcc -g main.c 然后用gdb gdb a.out执行它。加载后只需输入run来运行它,你就会看到分段错误。键入bt作为后跟踪。

答案 1 :(得分:0)

此行看起来很可疑

sort(&z[aux+1],l-aux);

l是长度,aux +是新的基本索引,所以新的长度应该是l - aux -1

然而正如其他人所说,你需要调试/放入诊断printfs。调试像离子屏这样的功能很难。

答案 2 :(得分:0)

正如几条评论所指出的那样,您可以使用gdb来查找Segmentation Fault的位置。我在原始代码上执行了此操作,发现它在行

处断开
p.distance=z[l-1].distance;  // statement 1

正如Malcolm所指出的,它发生的原因是你在递归调用sort函数时没有正确传递数组的长度。正确的递归调用应该是(记住c数组从零开始)

sort(z,aux); // left half of the array , excluding the pivot
sort(&z[aux+1],l-aux-1); // right half of the array.

此外,理想情况下应在检查后放置声明1,

if(l <= 1){return;}

注意,我如何将比较从l == 1更改为l&lt; = 1,因为您还必须检查l = 0的情况。即使在这些更改之后,遍历数组的循环也存在一些问题,在保持原始代码结构的同时,我试图尽可能地修复它。这是代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct 
{
char ID[8];
char Content[4];
int distance;

} DATA;


void sort(DATA *z, int l){

DATA p; //pivot
DATA t;
int aux=(l-1); //pivot's position
int i,j;




if(l <= 1){return;}
p.distance=z[l-1].distance;
for(i=0; i<l; i++){

if(i >= aux)
    break; // to avoid going over the right of pivot unnecessarily
if((z[i].distance)<(p.distance)){

    continue;
}


if((z[i].distance)>(p.distance)){

    t=z[i];

        for(j=i; j<aux; j++){

            z[j]=z[j+1];

        }

        z[aux]=t;
        aux--;
        i--; // You have changed the array and brought in a new element , 
       //and you should consider it too for comparison with pivot. 
}

}


sort(z,aux); // left half of the array , excluding the pivot
sort(&z[aux+1],l-aux-1); // right half of the array.

}

int main(){

DATA *z;
int l=5;
int i;

z=(DATA*)malloc(5*sizeof(DATA));

z[0].distance=5;
z[1].distance=1;
z[2].distance=4;
z[3].distance=3;
z[4].distance=2;

sort(z,l);

for(i=0; i<5; i++){

printf("%d\n",z[i].distance);
}

free(z);

}

但我建议您考虑以不同方式编写遍历循环,因为它现在围绕太多元素移动,实际上是O(n ^ 2)。而 使用quicksort所需的行为是O(n)。我建议在像CLRS算法手册这样的好书中查找算法。