C 我正在尝试对单个链接列表进行排序
我的代码是如此的错误!在输入和排序列表中的一些编号后,对于一些编号,它将不起作用并删除较旧的节点或不显示它们。不知道怎么了 有时它看起来工作正常,例如:我输入了4、6、7、2,它在排序列表中真实地显示出来。但输入3后,列表中没有显示3 这是我的密码:C 我正在尝试对单个链接列表进行排序,c,linked-list,C,Linked List,我的代码是如此的错误!在输入和排序列表中的一些编号后,对于一些编号,它将不起作用并删除较旧的节点或不显示它们。不知道怎么了 有时它看起来工作正常,例如:我输入了4、6、7、2,它在排序列表中真实地显示出来。但输入3后,列表中没有显示3 这是我的密码: if(head == NULL) { head = info; last = info; info->next = NULL; } else { if(info->number
if(head == NULL)
{
head = info;
last = info;
info->next = NULL;
}
else
{
if(info->number > last->number)
{
last->next = info;
last = info;
info->next = NULL;
}
else if (info->number < head->number )
{
info -> next = head;
head = info;
}
prev = head;
for(temp = head-> next ; temp!= NULL; temp = temp->next)
{
prev = prev->next;
if(info->number >temp->number)
{
temp->next = info;
}
else
{
temp-> prev = info;
info = prev;
}
}
}
if(head==NULL)
{
头=信息;
最后=信息;
信息->下一步=空;
}
其他的
{
如果(信息->编号>上次->编号)
{
最后->下一步=信息;
最后=信息;
信息->下一步=空;
}
否则如果(信息->编号<头部->编号)
{
信息->下一步=头部;
头=信息;
}
prev=头部;
对于(临时=头部->下一步;临时!=NULL;临时=临时->下一步)
{
上一个=上一个->下一个;
如果(信息->编号->临时->编号)
{
临时->下一步=信息;
}
其他的
{
temp->prev=信息;
信息=上一次;
}
}
}
这段代码没有任何意义,因为您提到了单链接列表,但在这里您使用了'temp->prev'
毫无疑问,代码中有减少代码大小的余地(if和else if检查可以删除,并直接执行“for”循环以插入新元素)if(head==NULL)
{
头=信息;
最后=信息;
信息->下一步=空;
最后=信息;
}
其他的
{
如果(信息->编号>头部->编号){
信息->下一步=头部;
头=信息;
}
否则{
tmp=上一个=水头;
而(tmp&(信息->编号编号))
{
prev=tmp;
tmp=tmp->next;
}
信息->下一步=上一步->下一步;
上一步->下一步=信息;
如果(!tmp)last=info;
}
}
考虑将其构建为一个数组,对数组进行排序,然后从中使用它。您使用的是冒泡排序,这不是最快的排序方式
幸运的是,您的C库很可能提供一种高效的快速排序算法(qsort
)。要将其用于链接列表,请执行以下操作:
- 分配(使用
)和指针数组,指针大小等于链表中的项数malloc
- 遍历链表,使数组的每个条目指向链表中的一个项目
- 使用
和指定的比较例程对指针进行排序qsort
- 遍历数组,根据需要设置每个元素的上一个和下一个指针(即完全忽略上一个链接)
- 释放阵列
next
和prev
指针更快,而且更不容易出错
如果您坚持使用冒泡排序,只需将第三步替换为冒泡排序。您不是在对“单链表”进行排序,而是在用户提供输入时尝试对列表进行排序。此外,您正在处理的列表看起来不像单个链接列表。它有“下一个”和“上一个”指针,所以它应该是一个“双链接列表”
从实现单个列表开始,将项目添加到末尾。只需稍加调整,您就可以将其排序。不要每次要添加项目时都转到列表的末尾,而是在列表中找到第一个大于或等于要添加项目的项目,并在其前面插入新项目。如果你找不到这样的东西,你就完了。你的物品会更大。只需将其添加到末尾。调试是一项需要学习的技能。最好现在就开始。设置一个断点,然后开始逐步检查代码,看看您是如何不符合假设的。我希望看到一个链表ADT和一个单独的排序方法。我不知道是你的列表不好还是排序实现不好。@Nodeum我认为对列表使用插入排序更好。我以前从未使用过调试,但现在是时候使用Thank@Vlad了,来自莫斯科,我只想使用我自己的算法,但似乎不起作用,谢谢你的建议。@ VladfromMoscow:我认为使用合并列表进行合并是更好的。这更多的是一个评论,然后是一个答案。我认为这更多的是一个答案。如果您要求容器井然有序,那么链表可能是错误的容器类型。。可以使用数组实现链表式结构。
if(head == NULL)
{
head = info;
last = info;
info->next = NULL;
}
else
{
if(info->number >= last->number) <-- CHANGE:: > changed to >= to take care of same number (as earlier stored number) being entered
{
last->next = info;
last = info;
info->next = NULL;
return; <-- CHANGE:return added here, no need to proceed further
}
else if (info->number <= head->number) <-- CHANGE:: < changed to <= to take care of same number (as earlier stored number) being entered
{
info -> next = head;
head = info;
return; <-- CHANGE:return added here, no need to proceed further
}
prev = head;
for(temp = head->next ; temp != NULL; temp = temp->next)
{
if(temp->number >= info->number) <-- CHANGE: modified code when insertion happens between head and last
{
prev->next = info;
info->next = temp;
break;
}
prev = temp;
}
}
else
{
temp-> prev = info;
info = prev;
}
if(head == NULL)
{
head = info;
last = info;
info->next = NULL;
last=info;
}
else
{
if(info->number>head->number){
info->next=head;
head = info;
}
else{
tmp=prev=head;
while(tmp && (info->number < tmp->number) )
{
prev=tmp;
tmp=tmp->next;
}
info->next=prev->next;
prev->next=info;
if(!tmp) last=info;
}
}