我如何冒泡排序链表?

时间:2016-01-06 08:30:31

标签: c

我正在尝试创建链接列表并按冒险排序对其进行排序。我成功地创建了链接列表,但是当我尝试冒泡它时,发生了一些事故,我不知道问题。有什么问题?

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

//the struct of LinkedList
typedef struct Node
{
    int data;
    struct Node * pNext;
}NODE,*PNODE;

PNODE createList();//Creat one LinkedList
int lengthList(PNODE pHead);//get the length of LinkedList
void sortList(PNODE);//bubble sort

int main()
{
    int length;
    PNODE pHead=NULL;
    pHead=createList();
    sortList(pHead);
    return 0;
}
//Create LinkedList
PNODE createList()
{
    int i,n;
    int val;
    PNODE pHead=(PNODE)malloc(sizeof(NODE));
    if(pHead==NULL)
    {
        printf("failed to create!\n");
        exit(-1);
    }
    pHead->pNext=NULL;
    PNODE pTail=pHead;
    printf("please input the length of the LinkedList:");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        printf("number %d is:\n",i+1);
        scanf("%d",&val);
        PNODE pNew=(PNODE)malloc(sizeof(NODE));
        if(pNew==NULL)
        {
            printf("failed to create\n");
            exit(-1);
        }
        pNew->data=val;
        pTail->pNext=pNew;
        pNew->pNext=NULL;
        pTail=pNew;
    }
    return pHead;
}
//get the length of LinkedList
int lengthList(PNODE pHead)
{
    int i=0;
    PNODE p=pHead->pNext;
    while(p!=NULL)
{
        i++;
        p=p->pNext;
    }
    return i;
}
//bubble sort
void sortList(PNODE pHead)
{
    int i,j,t,len;
    PNODE p,q;
    len=lengthList(pHead);
    p=pHead->pNext;
    for(i=0;i<len-1;i++)
    {
        for(j=0;j<len-i;j++)
        {
            q=p->pNext;
            if( p->data > q->data)
            {
                t=p->data;
                p->data=q->data;
                q->data=t;
            }
            p=q;//here may be the error
        }
    }
    return;
}

3 个答案:

答案 0 :(得分:0)

您正在sortList

中的列表末尾运行
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
    for(j=0;j<len-i;j++)
    {
        q=p->pNext;
        ....
        p=q;//here may be the error
    }
}

错误1)您的列表只有len长,但您尝试将p提升到p->pNext远远超过len次。

错误2)pHead不需要是一个完整的NODE - 它只是一个PNODE指针。你永远不会使用它的数据字段。你应该让pHead指向列表中的第一个节点,然后在pHead而不是pHead-> pNext开始你的迭代。

错误3)你永远不会清理内存分配。

答案 1 :(得分:0)

由于@Airsource指出了这些错误,请记住,大多数错误都是由于程序设计选择不当引起的。尝试像下面这样做&amp;你会遇到更少的错误

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

typedef struct _Node{
    int data;
    struct _Node* next;
}Node;

typedef struct {
    Node* headPtr;
    Node* tailPtr;
    unsigned size;
}List;

static void create_node(List* list, int element) {
    if (list->headPtr == NULL) {
        // List is empty
        list->headPtr = (Node* )malloc(sizeof(Node));
        list->headPtr->data = element;
        list->headPtr->next = 0;
        list->tailPtr = list->headPtr;
        list->size++;
    }else{
        // List was already populated
        Node* temp = (Node* )malloc(sizeof(Node));
        temp->data = element;
        temp->next = 0;
        list->tailPtr->next = temp;
        list->tailPtr = temp;
        list->size++;
    }
}

void create_list(List* list, int length){
    int ele;
    int i;
    list->headPtr = list->tailPtr = 0;
    list->size = 0;

    for (i = 0; i < length; i++) {
        scanf("%d", &ele);
        create_node(list, ele);
    }
}

void print_list(List* list){
    Node* loop = list->headPtr;
    while(loop){
        printf("%d ", loop->data);
        loop = loop->next;
    }
    printf("\n");
}


 int main(){
    List* list;
    int n;
    printf("Enter the length of the list: ");
    scanf("%d", &n);
    create_list(list, n);
    print_list(list);
    bubble_sort(list);
    print_list(list);
    if (cleanup(list))
        printf("Memory rescued!!\n");
    else
        printf("OOPS!! Error\n");
 return 0;
}

此外,您可以随时list->size获取尺寸。不需要单独的功能。

最后要使用冒泡排序对其进行排序,您可以执行以下操作

void bubble_sort(List* list) {
    int i, j;
    Node* first, *second;
    int temp;
    first = list->headPtr;
    second = list->headPtr->next;
    for (i = 0; i < list->size - 1; i++) {
        for (j = 0; j < list->size - i - 1; j++) {
            if (first->data > second->data){
                temp = first->data;
                first->data = second->data;
                second->data = temp;
            }
            first = second;
            second = second->next;
        }
        first = list->headPtr;
        second = list->headPtr->next;
    }
}

并进行清理,你可以这样做

bool cleanup(List* list) {
    Node* curr = list->headPtr;
    Node* nxt = list->headPtr->next;
    while(nxt){
        free(curr);
        curr = nxt;
        nxt = curr->next;
    }
    list->headPtr = list->tailPtr = 0;
    list->size = 0;
    return !nxt ? true: false;
}

答案 2 :(得分:0)

你的程序中有几个错误。我将逐一解决这些问题:

  1. 第28行PNODE pHead=(PNODE)malloc(sizeof(NODE)); 在这里,您要在检查n> 0之前分配内存并创建节点。

  2. 第36行printf("please input the length of the LinkedList:");
    到目前为止,您已经创建了一个节点head节点,其中包含 no 值(因此包含垃圾)

  3. 实际上,您的createList()会创建一个包含n+1个节点而不是n的链接列表,而head->value包含垃圾。

    解决方案:

    printf("please input the length of the LinkedList:");
    scanf("%d", &n);
    for(i=0; i<n; i++)
    {
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
    
        if(pNew == NULL)
        {
            printf("failed to create!\n");
            exit(-1);
        }
    
        scanf("%d", &val);
        pNew->data = val;
        pNew->pNext = NULL;
    
        if (!i)
            pHead = pNew;
        else
            pTail->pNext = pNew;
        pTail = pNew;      
    }
    
    return pHead;
    
    1. 第59行PNODE p=pHead->pNext;
      在这里,您要计算从第二个节点开始的节点(省略head)。难怪您将length作为n获得,因为您在n+1
    2. 中创建了长度为createList()的链接列表

      想象一下如果n = 0pHead = NULL会是什么? 然后这一行将导致SegFault

      解决方案:
      PNODE p=pHead->pNext;更改为PNODE p = pHead;

      1. 第73行p=pHead->pNext;
        在这里,您将开始排序,排除第一个节点head节点 此外,这应该在内部for内部以及内部for之外,以便为每次传递将p重置为第一个节点。

      2. 第76行for(j=0;j<len-i;j++)
        这里的j必须小于len - 1 - i,因为在第1行(i = 0)中,在最坏的情况下j对于len-1将等于j < len-i,其中p将指向链接列表的最后一个节点,q将为q = p -> pNext为NULL。这会使q->data导致SegFault

      3. 总而言之,您的排序例程在第一个Pass中生成SegFault,即使它没有(通过正确调整内部for中的循环终止表达式)外部{除了增加时间复杂度之外,{1}}循环对排序没有贡献。

        解决方案:

        for

        一个问题:
        你如何检查元素是否已经分类? for(i = 0; i < len - 1; i++) { p = pHead; for(j = 0; j < len - 1 - i; j++) { q = p -> pNext; if(p->data > q->data) { t = p -> data; p -> data = q -> data; q -> data = t; } p = q; } } 例程有助于发现上述错误。

        &#34;在处理输入之前,请务必先验证是否正确存储了输入!&#34;