連結串列排序——插入排序(純C語言版)
阿新 • • 發佈:2018-12-30
/* ========================== 功能:直接插入排序(由小到大) 返回:指向連結串列表 頭的指標 ========================== */ /* 直接插入排序的基本思想就是假設連結串列的前面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罷了。 這一點請讀者務必搞清楚,要不然就可能認為它和上面的選擇排序法一樣了。 */ struct student *InsertSort(struct student *head) { struct student *first; /*為原連結串列剩下用於直接插入排序的節點頭指標*/ struct student *t; /*臨時指標變數:插入節點*/ struct student *p; /*臨時指標變數*/ struct student *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; }