C语言中链表的快速排序
好了,伙计们,在gdb和valgrind没有成功之后,我谦虚地向你们提出我的问题。我们被要求用c语言实现一个快速排序版本,使用列表的第一个元素作为轴心(以保持与我们在本学期早些时候所做的简单haskell实现的可比性)。列表实现已经提供(制作、打印和结构定义),其余的由我们决定。我(惊讶,惊讶)收到了一个segfault,但是valgrind发现了大量错误和堆栈溢出,所以也许一些新的眼睛可以帮助我 我的代码:C语言中链表的快速排序,c,segmentation-fault,stack-overflow,quicksort,C,Segmentation Fault,Stack Overflow,Quicksort,好了,伙计们,在gdb和valgrind没有成功之后,我谦虚地向你们提出我的问题。我们被要求用c语言实现一个快速排序版本,使用列表的第一个元素作为轴心(以保持与我们在本学期早些时候所做的简单haskell实现的可比性)。列表实现已经提供(制作、打印和结构定义),其余的由我们决定。我(惊讶,惊讶)收到了一个segfault,但是valgrind发现了大量错误和堆栈溢出,所以也许一些新的眼睛可以帮助我 我的代码: #include <stdio.h> #include <s
#include <stdio.h>
#include <stdlib.h>
typedef struct CELL *LIST;
struct CELL {
int element;
LIST next;
};
LIST MakeList();
void PrintList(LIST);
LIST qSort(LIST);
int listLength(LIST);
LIST combine(LIST, LIST, LIST);
int main(){
LIST list;
printf ("enter a several numbers separated by spaces or returns and ended by Ctrl-D\n");
list = MakeList();
PrintList(qSort(list));
return 0;
}
LIST qSort(LIST list){
LIST current, pivot = list, temp = NULL;//use first element as pivot, start comparison at list->next
LIST little, big, littleHead, bigHead;
little = (LIST) malloc(sizeof(struct CELL));
little->element = 0;
little->next = NULL;
littleHead = little;
big = (LIST) malloc(sizeof(struct CELL));
big->element = 0;
big->next = NULL;
bigHead = big;
if(listLength(list) <= 1){//base case
return list;
}
//remove pivot by setting current to list->next
current = list->next;
do{
if(current->element <= pivot->element){
little->element = current->element;
little->next = (LIST) malloc(sizeof(struct CELL));
little = little->next;
little->next = NULL;
}
else{
big->element = current->element;
big->next = (LIST) malloc(sizeof(struct CELL));
big = big->next;
big->next = NULL;
}
current = current->next;
}while(current != NULL);
littleHead = qSort(littleHead);
bigHead = qSort(bigHead);
return combine(littleHead, bigHead, pivot);
}
int listLength(LIST list){
int length = 0;
LIST current = list;
if(NULL==list){
return length;
}
else{
while(current != NULL){
current = current->next;
length++;
}
}
return length;
}
LIST combine(LIST little, LIST big, LIST pivot){
LIST temp = little;
while(temp->next != NULL){
temp = temp->next;
}
temp->next = pivot;
pivot->next = big;
return little;
}
LIST MakeList()
{
int x;
LIST pNewCell;
if (scanf("\%d", &x) == EOF) return NULL;
else {
pNewCell = (LIST) malloc(sizeof(struct CELL));
pNewCell->next = MakeList();
pNewCell->element = x;
return pNewCell;
}
}
void PrintList(LIST list)
{
while (list != NULL) {
printf("\%d\n", list->element);
list = list->next;
}
}
首先要解决一些问题:
if (scanf("\%d", &x) == EOF) return NULL;
不需要\号。这可能更容易检查!=1,因为您期望一个值
这导致您的MakeList无限递归(至少在我的机器上)
在qsort函数中,小列表和大列表的末尾总是有一个虚拟条目——由以下代码完成
little->next = (LIST) malloc(sizeof(struct CELL));
little = little->next;
little->next = NULL;
这意味着,当你拆分列表时,你总是会得到比开始更多的条目,所以它永远不会结束。还请注意,这些新条目没有设置其元素值,这可能就是您收到未初始化警告的地方
您应该重新考虑如何存储子列表,可能以NULL开头,以指示为空,尽管这会使添加新值变得更加困难。您可以如下编辑makelist函数 你将观察到一些变化
scanf
通过删除\
是正确的(参考黑暗势力的答案)scanf
read-in-while,这将确保如果您输入任何不兼容的输入,如任何字母而不是Ctrl+D,则读取将停止scanf的实现实际上是由prof提供的。它需要一个Ctrl-D来结束这个列表,据我所知,它在我们的unix机器上模拟了一个EOF。这有点怪,但我想他有点懒。谢谢你的建议,不过,我会弄乱我的子列表存储和报告回来。
little->next = (LIST) malloc(sizeof(struct CELL));
little = little->next;
little->next = NULL;
LIST MakeList()
{
int x;
LIST pNewCell;
while(scanf("%d", &x))
{
pNewCell = (LIST) malloc(sizeof(struct CELL));
pNewCell->next = MakeList();
pNewCell->element = x;
return pNewCell;
}
return NULL;
}