[英]Infinite loop while sorting a linked list in C
我是C编程的新手,必须对链接列表进行排序。 该链表表示已由用户输入创建的多项式。 每个节点都有一个系数和一个幂。 当我尝试对列表进行排序并将其返回到打印它的主函数时,没有打印任何内容(我认为我的程序永远不会退出while
循环)。
在这里,我创建结构:
struct node
{
int sunt;
int dun;
struct node* next;
};
typedef struct node* Poly;
这是我对列表进行排序的代码( head
是我的初始列表的名称):
struct node* poly = head;
struct node* temp;
int length = 0;
while (poly != NULL)
{
length++;
poly = poly->next;
}
poly = head;
while (length > 0)
{
int i = 0;
while ((poly != NULL) && (poly->next != NULL))
{
if (poly->dun > poly->next->dun)
{
temp = poly;
poly = poly->next;
poly->next = temp;
if(i = 0)
{
head = poly;
}
i ++;
}
else
{
if(i = 0)
{
head = poly;
}
i ++;
}
poly = poly->next;
}
length --;
poly = head;
}
return head;
这是我在主函数中打印列表的位置(POLYmake函数是我创建和排序列表的位置):
poly1 = POLYmake();
while(poly1 != NULL)
{
printf("%d %d \n", poly1->sunt, poly1->dun);
poly1 = poly1->next;
}
我知道这很复杂,但是我没有C方面的经验,希望您能对我有所帮助。
这个循环
while(length > 0)
永远都是正确的,因为当您完成遍历列表时,只将其递减1。
另外,以下代码:
if(i = 0)
{
head = poly;
}
应该
if(i == 0)
{
head = poly;
}
首先...
if(i=0)
是错的,因为它设置了我
尽管我认为还有更多...您正在设置下一个节点->接下来是当前节点,反之亦然,但是,您没有在设置上一个节点->下一个或下一个节点->下一个,因此,您很可能会创建一个循环,即下一个循环都包含相同的指针。 您需要绑扎列表中的所有链接才能执行此操作,这很痛苦!
所以应该是:
node* prev = null
[...] ensure you set the prev after each iteration
then
node* swap1 = poly;
node* swap2 = poly->next;
swap1->next = swap2->next; (which you'd have to null check for beforehand)
swap2->next = swap1;
prev->next = swap2;
但是:从概念上讲,您是在交换整个链接,只是交换一些数字。 您可以在链表条目中嵌入一个结构指针(包含您感兴趣的ACTUAL值),然后交换它们,而不是动态地重组列表本身。
这个故事的寓意是,链表不是冒泡排序的最佳结构。
我认为您打破了链接列表,并在内环的第一个if分支中形成了一个循环
temp = poly; // (1)
poly = poly->next; // (2)
poly->next = temp; // (3)
假设您有一个列表a-> b-> c-> ...,然后输入if,则poly指向(1)之后的so temp。 在(2)之后,poly将指向b。 然后,(3)语句将b的下一个指针分配给temp,即a。 这会导致循环a-> b-> a-> b-> ...,而您永远不会到达c,因此永远停留在循环中。 如果交换a和b,则应将a的下一个指针设置为c。
编辑:此外,上一个节点(下一个指针指向poly的节点)也必须更新。 为此,可以将前一个节点保留在单独的prev
指针中,并且可以将prev->next
设置为交换后两个节点中的第一个的那个节点。
让我们专注于这个
temp = poly;
poly = poly->next;
poly->next = temp;
大概的想法是交换列表中的两个元素。 所以我们来看一个清单
item1 -> item2 -> item3 -> item4 -> NULL
假设item2处有多边形点,您需要将其与item3交换。 您要做的第一件事是将temp设置为poly,因此temp和poly都指向item2。
item1 -> item2 -> item3 -> item4 -> NULL
poly
temp
然后将poly移至指向item3的poly-> next
item1 -> item2 -> item3 -> item4 -> NULL
poly
temp
然后设置多边形的下一个指针指向温度为item2
V------------
item1 -> item2 -> item3 -| item4 -> NULL
poly
temp
请注意,现在没有任何东西指向item4。 这是内存泄漏。 还要注意,列表以循环结尾,这意味着您永远不会遇到NULL,也永远不会退出内部循环。
如何解决呢?
您会注意到,poly之前的项目也将需要更改其下一个指针,因此您将需要前一个指针。 这就是我会做的
// Set up the loop before you start
struct node* previous = NULL;
poly = head;
while (poly != NULL && poly->next != NULL)
{
if (poly->dun > poly->next->dun)
{
if (previous == NULL)
{
head = poly->next;
}
else
{
previous->next = poly->next;
}
struct node* tail = poly->next->next;
poly->next->next = poly;
poly->next = tail;
}
previous = poly;
poly = poly->next;
}
我认为那行得通。 尚未测试。
用实际代码显示了一个简单的算法。
typedef struct node Node;
Node *bubbleSort(Node *head){
if(head == NULL || head->next == NULL)//no need sort
return head;
Node anchor = { 0, 0, head }, *sentinel = NULL;
while(1){
Node *prev = &anchor, *curr = prev->next, *next = curr->next;
if(next == sentinel)
break;
while(next != sentinel){
Node *rest = next->next;
// prev --> curr --> next --> rest
if(curr->dun > next->dun){
prev->next = next;
next->next = curr;
curr->next = rest;
prev = next;
//curr = curr;
next = curr->next;
} else {
prev = curr;
curr = curr->next;
next = curr->next;
}
}
sentinel = curr;
}
return anchor.next;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.