簡體   English   中英

在C中對鏈表進行排序時出現無限循環

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM