简体   繁体   English

如何对链接列表进行冒泡排序?

[英]How do I Bubble Sort a linked list?

I am trying to create a linked list and sort it by Bubble Sort. 我正在尝试创建一个链接列表,并按气泡排序对其进行排序。 I succeeded to create the linked list, but when I am trying to Bubble Sort it, some accidents occur and I do not know the problem. 我成功创建了链接列表,但是当我尝试对气泡列表进行排序时,会发生一些意外,并且我不知道问题所在。 What is the problem? 问题是什么?

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

You are running off the end of your list in sortList 您正在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
    }
}

Bug 1) Your list is only len long but you are attempting to advance p to p->pNext far more then len times. 错误1)您的列表只有len长,但您正尝试将p推进到p->pNext远超过len倍。

Bug 2) pHead does not need to be a full NODE - it's just a PNODE pointer. 错误2)pHead不必是完整的NODE-它只是PNODE指针。 You never use its data field. 您永远不会使用其数据字段。 You should have pHead point to the first node in the list, and then start your iteration at pHead rather than pHead->pNext. 您应该让pHead指向列表中的第一个节点,然后从pHead而不是pHead-> pNext开始迭代。

Bug 3) You never clean up your memory allocations. 错误3)您永远不会清理内存分配。

As @Airsource pointed out the bugs, keep in mind most of them are caused because of poor designing choice of your program. 正如@Airsource指出的错误,请记住,大多数错误是由于程序的设计选择不当造成的。 Try to do it like below & you will run into less errors 尝试像下面那样做,您将遇到更少的错误

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

Moreover, you can get the size anytime just by list->size . 而且,您可以随时通过list->size No need for separate function to do that. 无需单独的功能即可执行此操作。

Finally to sort it using bubble sort you could do something like this below 最后,使用气泡排序对其进行排序,您可以在下面执行以下操作

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

and for cleanup you do this 为了清理,您可以这样做

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

There are couple of bugs in your program. 您的程序中有几个错误。 I will address them one by one: 我将一一解答:

  1. Line 28 PNODE pHead=(PNODE)malloc(sizeof(NODE)); 第28行PNODE pHead=(PNODE)malloc(sizeof(NODE)); Here you are allocating a memory and creating a node before checking if n>0 or not. 在这里,在检查n是否大于0之前,您正在分配内存并创建节点。

  2. Line 36 printf("please input the length of the LinkedList:"); 第36行printf("please input the length of the LinkedList:");
    Now up to this point you have created a one node, head node which has no value in it (so contains garbage) 至此,您已经创建了一个节点,其中的head节点没有任何值(因此包含垃圾)

In effect your createList() creates a linked list with n+1 nodes instead of n and the head->value contains garbage. 实际上,您的createList()创建的链表具有n+1节点而不是n ,并且head->value包含垃圾。

Solution: 解:

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. Line 59 PNODE p=pHead->pNext; 第59行PNODE p=pHead->pNext;
    Here you are counting nodes starting from the second node (leaving out head ). 在这里,您正在计算从第二个节点开始的节点(不包括head )。 No wonder you will get length as n as you have created a linked list of length n+1 in your createList() 难怪你会得到lengthn为您创建长度的链表n+1createList()

Imagine what if n = 0 and thus pHead = NULL ? 想象一下,如果n = 0从而pHead = NULL怎么办?
Then this line will result in SegFault . 然后此行将导致SegFault

Solution: 解:
change PNODE p=pHead->pNext; 更改PNODE p=pHead->pNext; to PNODE p = pHead; PNODE p = pHead;

  1. Line 73 p=pHead->pNext; 第73行p=pHead->pNext;
    Here you will start sorting excluding the first node, head node. 在这里,您将开始排序,排除第一个节点( head节点)。
    Also this should be inside the outter for and outside of the inner for to reset the p to first node for each pass. 也这应该是outter内for和外部内的for给复位p为每个通第一个节点。

  2. Line 76 for(j=0;j<len-i;j++) 第76行for(j=0;j<len-i;j++)
    Here j must be less than len - 1 - i as in pass 1 ( i = 0 ) in the worst case j will be equal to len-1 for j < len-i , where p will point to the last node of linked list and q will be NULL as q = p -> pNext . 这里j必须小于len - 1 - i如在传递1( i = 0 )时,在最坏的情况下j等于len-1 j < len-i ,其中p指向链表的最后一个节点当q = p -> pNextq将为NULL。 Which will make q->data to result in SegFault . 这将使q->data产生SegFault

To summarise, your sort routine is producing SegFault in the very first Pass and even if it didn't (by properly adjusting the loop-terminating expression in inner for ) the outer for loop is contributing nothing towards the sorting except increasing the time complexity. 总而言之,您的排序例程在第一次通过时就产生了SegFault ,即使它没有(通过适当地调整内部for的循环终止表达式),外部for循环也没有对排序做出任何贡献,只是增加了时间复杂度。

Solution: 解:

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

A question: 一个问题:
How are you checking whether element have been sorted or not? 您如何检查元素是否已排序?
A printList() routine would have been helpful in spotting the above bugs. printList()例程将有助于发现上述错误。

"Always verify whether you correctly stored the input or not by explicitly printing the same before processing it!" “始终通过在处理输入之前显式打印输入来验证您是否正确存储了输入!”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM