鏈表的插入排序

/*
==========================
 功能:直接插入排序(由小到大)
 返回:指向鏈表表 頭的指針
==========================
*/
/*
 直接插入排序的基本思想就是假設鏈表的前面n-1個節點是已經按鍵值
 (就是用它排序的字段,我們取學號num爲鍵值)排好序的,對於節點n在
 這個序列中找插入位置,使得n插入後新序列仍然有序。按照這種思想,依次
 對鏈表從頭到尾執行一遍,就可以使無序鏈表變爲有序鏈表。
 
單向鏈表的直接插入排序圖示:
---->[1]---->[3]----> [2]...---->[n]---->[NULL](原鏈表)
head   1->next  3->next  2->next   n->next

---->[1]---->[NULL](從原鏈表中取第1個節點作爲只有一個節點的有序鏈表)
head
圖11

---->[3]---->[2]...---->[n]---->[NULL](原鏈表剩下用於直接插入排序的節點)
first   3->next  2->next   n->next
圖12

---->[1]---->[2]---->[3]...---->[n]---->[NULL](排序後鏈表)
head   1->next  2->next  3->next   n->next

圖13:有N個節點的鏈表直接插入排序

1、先在原鏈表中以第一個節點爲一個有序鏈表,其餘節點爲待定節點。
2、從圖12鏈表中取節點,到圖11鏈表中定位插入。
3、上面圖示雖說畫了兩條鏈表,其實只有一條鏈表。在排序中,實質只增加了一個用於指向剩下需要排序節點的頭指針first罷了。
   這一點請讀者務必搞清楚,要不然就可能認爲它和上面的選擇排序法一樣了。
*/
node *InsertSort(node *head)
{
    node *first; /*爲原鏈表剩下用於直接插入排序的節點頭指針*/
    node *t; /*臨時指針變量:插入節點*/
    node *p; /*臨時指針變量*/
    node *q; /*臨時指針變量*/

    first = head->next; /*原鏈表剩下用於直接插入排序的節點鏈表:可根據圖12來理解。*/
    head->next = NULL; /*只含有一個節點的鏈表的有序鏈表:可根據圖11來理解。*/

    while (first != NULL) /*遍歷剩下無序的鏈表*/
    {
        /*注意:這裏for語句就是體現直接插入排序思想的地方*/
        for (t = first, q = head; ((q != NULL) && (q->num < t->num)); p = q, q = q->next); /*無序節點在有序鏈表中找插入的位置*/
    
    /*退出for循環,就是找到了插入的位置*/
    /*注意:按道理來說,這句話可以放到下面註釋了的那個位置也應該對的,但是就是不能。原因:你若理解了上面的第3條,就知道了。*/
        first = first->next; /*無序鏈表中的節點離開,以便它插入到有序鏈表中。*/ 
  
        if (q == head) /*插在第一個節點之前*/
        {
            head = t;
        }
        else /*p是q的前驅*/
        {
            p->next = t;
        }
        t->next = q; /*完成插入動作*/
        /*first = first->next;*/
    }
    return head;
}

發佈了58 篇原創文章 · 獲贊 21 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章