Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中链表的快速排序_C_Segmentation Fault_Stack Overflow_Quicksort - Fatal编程技术网

C语言中链表的快速排序

C语言中链表的快速排序,c,segmentation-fault,stack-overflow,quicksort,C,Segmentation Fault,Stack Overflow,Quicksort,好了,伙计们,在gdb和valgrind没有成功之后,我谦虚地向你们提出我的问题。我们被要求用c语言实现一个快速排序版本,使用列表的第一个元素作为轴心(以保持与我们在本学期早些时候所做的简单haskell实现的可比性)。列表实现已经提供(制作、打印和结构定义),其余的由我们决定。我(惊讶,惊讶)收到了一个segfault,但是valgrind发现了大量错误和堆栈溢出,所以也许一些新的眼睛可以帮助我 我的代码: #include <stdio.h> #include <s

好了,伙计们,在gdb和valgrind没有成功之后,我谦虚地向你们提出我的问题。我们被要求用c语言实现一个快速排序版本,使用列表的第一个元素作为轴心(以保持与我们在本学期早些时候所做的简单haskell实现的可比性)。列表实现已经提供(制作、打印和结构定义),其余的由我们决定。我(惊讶,惊讶)收到了一个segfault,但是valgrind发现了大量错误和堆栈溢出,所以也许一些新的眼睛可以帮助我

我的代码:

    #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;
    }