【问题标题】:Quick_Sort in Single Linked List [closed]单链表中的快速排序[关闭]
【发布时间】:2015-08-01 09:37:48
【问题描述】:

我正在尝试对单个链表应用快速排序。我创建了分区函数,该函数通过将第一个元素视为枢轴来工作:

list->19->8-17->15->25->41
After calling partition(&list) we get :
list->16->17->8->19->25->41

这就是我想要做的:

1.)我在 list->19->8-17->15->25->41 上调用 Quicksort()

2.)在 QuickSort 中,我们调用 list 上的分区,所以我得到 list->16->17->8->19->25->41 ,这里的 'q' 指向枢轴元素。

3.)现在使用 q 我们将列表分成两部分:list1->16->17->8->Null 和 list2->25->41,然后在 list1 和列表 2 上调用快速排序

4.) 然后我用 'q' 加入两个列表。

但是我的程序在 Windows 中崩溃可能是由于分段错误。有人可以帮我吗?

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

struct node{
    int data;
    struct node * next;
};

typedef struct node Node;

void display(Node *p){
    while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}

Node * create(int d){
    Node *p=(Node *)malloc(sizeof(Node));
    p->data=d;
    p->next=NULL;
    return p ;
}

Node * partition(Node **head){
    Node *list=*head;
    Node *pv=*head;
    int pivot=list->data;
    Node *p=list->next;
    Node *temp,*q=list;

    while(1){
        if(!p)
            break;

        if(p->data<pivot){
            temp=p;
            q->next=temp->next;
            p=p->next;
            temp->next=list;
            list=temp;
        }
        else{
            q=p;
            p=p->next;
        }
    }
    *head=list;
    return pv ;
}

Node * quicksort(Node * list){



    if(list==NULL || (list)->next==NULL)
        return list;
    Node * q,*list1,*list2,* temp;
    q=partition(&list);

    list1=list;

    list2=q->next;
    temp=list1;

    while(1){
        if(temp->next==q)
        {
            temp->next=NULL;
            break;

        }
        temp=temp->next;

    }

    list1=quicksort(list1);
    list2=quicksort(list2);
    temp=list1;
    while(temp->next!=NULL)
        temp=temp->next;
    temp->next=q;
    q->next=list2;
    return list1;
}





int main(){

    Node *list1=create(19),*list2;
    Node *a=create(8);
    Node *b=create(17);
    Node *c=create(16);
    Node *d=create(25);
    Node *e=create(41);
    list1->next=a;a->next=b;b->next=c;c->next=d;d->next=e;

    list1=quicksort(list1);
    display(list1);


}

【问题讨论】:

  • 你应该做一些调试。
  • @OliverCharlesworth 你的意思是 SO 不是分布式调试服务?
  • @JohnColeman 上周。本周,它正在回答关于没人会写的愚蠢代码的问题,例如:stackoverflow.com/questions/31759349/…
  • 下周将重复解释 do..while 循环条件中的复合布尔表达式。
  • @rcgldr 这就是我正在做的事情,我正在找出第一个列表的最后一个元素并将其设置为 NULL

标签: c algorithm sorting


【解决方案1】:

此时在while(1)循环中:

       if(temp->next==q)

temp 可以等于 q(当 pivot 小于 list 的其余部分时),所以 temp->next 永远不会等于 q,并且当 temp->next == NULL 时发生分段错误,然后执行 temp = temp->下两次。

自下而上的合并排序会更好,但我假设这只是一个学习练习。

update - 一种快速自下而上的链表合并排序,它使用指向节点的指针数组,其中 array[i] 指向一个大小为 2 到 i 次方节点的列表(或者它是 NULL)。节点一次合并到一个数组中,然后当所有节点都合并到数组中时,将数组合并为一个排序列表。

#define NUMLISTS 32                     /* number of lists */

typedef struct NODE_{
struct NODE_ * next;
int data;
}NODE;

NODE * MergeLists(NODE *, NODE *);

NODE * SortList(NODE *pList)
{
NODE * aList[NUMLISTS];                 /* array of lists */
NODE * pNode;
NODE * pNext;
int i;
    if(pList == NULL)                   /* check for empty list */
        return NULL;
    for(i = 0; i < NUMLISTS; i++)       /* zero array */
        aList[i] = NULL;
    pNode = pList;                      /* merge nodes into aList[] */
    while(pNode != NULL){
        pNext = pNode->next;
        pNode->next = NULL;
        for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
            pNode = MergeLists(aList[i], pNode);
            aList[i] = NULL;
        }
        if(i == NUMLISTS)
            i--;
        aList[i] = pNode;
        pNode = pNext;
    }
    pNode = NULL;                       /* merge array into one list */
    for(i = 0; i < NUMLISTS; i++)
        pNode = MergeLists(aList[i], pNode);
    return pNode;
}

NODE * MergeLists(NODE *pSrc1, NODE *pSrc2)
{
NODE *pDst = NULL;                      /* destination head ptr */
NODE **ppDst = &pDst;                   /* ptr to head or prev->next */
    while(1){
        if(pSrc1 == NULL){
            *ppDst = pSrc2;
            break;
        }
        if(pSrc2 == NULL){
            *ppDst = pSrc1;
            break;
        }
        if(pSrc2->data < pSrc1->data){  /* if src2 < src1 */
            *ppDst = pSrc2;
            pSrc2 = *(ppDst = &(pSrc2->next));
            continue;
        } else {                        /* src1 <= src2 */
            *ppDst = pSrc1;
            pSrc1 = *(ppDst = &(pSrc1->next));
            continue;
        }
    }
    return pDst;
}

【讨论】:

  • 是的,这就是问题所在。非常感谢。我更改了代码,现在可以正常工作了。
猜你喜欢
  • 1970-01-01
  • 2015-02-10
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
相关资源
最近更新 更多