[英]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: 我将一一解答:
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之前,您正在分配内存并创建节点。
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;
PNODE p=pHead->pNext;
第59行PNODE p=pHead->pNext;
head
). 在这里,您正在计算从第二个节点开始的节点(不包括head
)。 No wonder you will get length
as n
as you have created a linked list of length n+1
in your createList()
难怪你会得到length
为n
为您创建长度的链表n+1
在createList()
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;
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
为每个通第一个节点。
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 -> pNext
, q
将为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.