[英]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.