簡體   English   中英

交換冒泡排序雙向鏈表的節點 C

[英]swapping nodes for a bubble sort doubly linked list C

哎呀,我回來了。 我現在正在嘗試使用節點交換進行冒泡排序。 我的算法中有一個我無法確定的問題。 當我刪除 bool 條件以確定列表是否已排序時,程序會生成一些 output,表明循環條件失敗是算法中的問題。 我已經用圖表說明了紙上發生的事情,每個指針都被重新分配了。 我設想節點 ab c d,其中 b 和 c 交換。 排序 function 如下。 我已經為每一個動作做了筆記,試圖找出我做錯了什么。 沒有骰子,任何指導將不勝感激,謝謝。

void sortList(void)
{
    struct Node *before, *after;
    struct Node * temp;

    bool sorted = false;

    while (sorted == false)
    {
        //test completion
        sorted = true;  //if this isn't changed by the below statement the list is sorted
        temp = head;    //reinitializes where there list sorts from
        while (temp->next != NULL)  //stops at the end of the list
        {
            if (temp->data > temp->next->data)
            {
                //test the value of the nodes to see if they need a sort

                before = temp->prev;    //"back" pointer for subject (b)
                after = temp->next; //"forward" pointer for subject
                if (before != NULL)
                {
                    before->next = after;   //covers swap being made at beginning
                }
                temp->next = after->next;   //points to after next
                after->next->prev = temp;   //sets prev pointer for "d"
                temp->prev = after; //points to what after pointed
                after->next = temp; //places node after next one
                after->prev = before;   //ditto

                sorted = false; //flagged, the list is not sorted
            }
            temp = temp->next;  //moves through the list

        }
    }
}

原來的sortList function主要存在三個問題:

  1. 移動列表中的第一個節點時,它不會更新head (修復:添加一個else部分來更新head 。)
  2. after- after->next->prev取消引用列表末尾的 null 指針。 (修復:先檢查after->next != NULL 。)
  3. temp = temp->next在列表末尾取消引用 null 指針,並在不在列表末尾時跳過 position。 temp節點與以下節點交換的代碼已經通過列表將temp節點 position 推進,因此不應再次執行此操作。 (修復:將temp = temp->next;移動到僅在不需要交換temp節點時才執行的else部分。)

這是sortList()的更新版本,其中標記了更改:

void sortList(void)
{
    struct Node *before, *after;
    struct Node * temp;

    bool sorted = false;

    while (sorted == false)
    {
        //test completion
        sorted = true;  //if this isn't changed by the below statement the list is sorted
        temp = head;    //reinitializes where there list sorts from
        while (temp->next != NULL)  //stops at the end of the list
        {
            if (temp->data > temp->next->data)
            {
                //test the value of the nodes to see if they need a sort

                before = temp->prev;    //"back" pointer for subject (b)
                after = temp->next; //"forward" pointer for subject
                if (before != NULL)
                {
                    // temp is not at beginning of list
                    before->next = after;
                }
                else
                {
                    // *** Fix 1 ***
                    // temp is at beginning of list
                    head = after;
                }
                temp->next = after->next;   //points to after next
                if (after->next != NULL) // *** Fix 2 ***
                {
                    after->next->prev = temp;   //sets prev pointer for "d"
                }
                temp->prev = after; //points to what after pointed
                after->next = temp; //places node after next one
                after->prev = before;   //ditto

                sorted = false; //flagged, the list is not sorted
            }
            else // *** Fix 3 ***
            {
                temp = temp->next;  //moves through the list
            }

        }
    }
}

編輯

由於 temp- temp->next取消引用 null 指針,當headNULL (空列表)時,上述版本的sortList失敗。 修復它的一種方法是通過更改 sorted 的初始化將空列表標記為已sorted ,如下所示:

    bool sorted = (head == NULL);

通過在外循環的每次迭代之后將內循環的迭代次數減少一次, sortList完成的工作量可以(大約)減半。 這可以按如下方式完成:

  1. 添加一個新變量done以在列表末尾標記已排序部分的開始。 將其初始化為NULL頂部附近的 NULL(在外循環之前):
    struct Node *done = NULL;
  1. 將內部循環的條件更改為在列表的未排序部分的末尾終止:
    while (sorted == false)
    {
        //test completion
        sorted = true;  //if this isn't changed by the below statement the list is sorted
        temp = head;    //reinitializes where there list sorts from
        while (temp->next != done) // stops at the sorted portion of the list
        {
  1. 當內部循環終止時(在外部循環結束時), temp節點和它之外的所有內容現在都已排序,因此將done指向該節點:
        }
        done = temp;    // everything from here is already sorted
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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