節點值交換法:
設置兩個鏈表指針p、q,第一個用來指向頭結點后一個(head->next)(每次內層循環結束,則往后移動),第二個用來繼承當前p節點后一個(p ->next),在內層循環中不斷往后移動,期間滿足交換條件則交換,直至排序完畢。實際上與用指針做冒泡排序時一樣。
下圖幾個大步驟展示了排序過程,這里用數組(5、4、3、2、1)做為例子(圖中p、q 是鏈表指針):
綜上所述,我們可以寫出冒泡排序代碼:
struct bubbleSort { int data; struct bubbleSort * next; }; /* * 初始條件:已創建鏈表bubbleSort * 設置兩個鏈表指針 bubbleSort *p, *q */ void BubbleSort(bubbleSort * head) { for(p = head -> next; p != NULL; p = p -> next) for(q = p -> next; q != NULL; q = q -> next) if((p -> data) > (q -> data)) int s = q -> data, q -> data = p -> data, p -> data = s; }
# 2017 10.7 16:55:54
交換節點法:
最近看到有關鏈表的冒泡排序除了交換值的方法還有一種交換節點的方法...實際上,感覺和鏈表的反轉有幾分相似,於是想了一會寫了一下,但還是有問題,於是還是借鑒了別人的實現方法。
先解釋一下實現交換節點的重要代碼部分:
比如,排序5個數:{5,4,3,2,1}。
p = head;
q = head -> next;
p->next = q->next;
q->next = q->next->next;
p->next->next = q;
q = p->next;
從上面第5行開始解釋:
第5行:把頭節點的后一個(數據5節點)指向數據5節點的后一個(數據4節點)。
第6行:接着把數據5節點的后一個指向數據4節點的后一個(數據3節點)。
第7行:再把數據5的節點接到數據4節點的后面,上一行已經把數據3節點接到了數據5節點的后面了,所以,這樣數據5節點就插進了數據4節點和數據3節點之間,數據3節點的位置又回到了原來的位置。
第8行:最后q = p->next;是什么意思呢?我們看一下第5行知道p->next已經變為了q->next; 中間p->next也沒有其他的變化,所以我們可以理解為最開始的數據5的節點變為了數據4的節點,向后移動了一個。實際上是重新將指針指向第一個節點,向前移動了一個。
這里鏈表中的節點就變為了 4->5->3->2->1.
然后判斷完后面還有兩句:
q = q->next;
p = p->next;
這兩句的意思是使鏈表往后移動,不管前一個和后一個是否進行了交換都應該往后移動,以使后面需要的交換的節點也能正常進行。
然后給一個別人的節點交換的正確代碼地址:點擊(•̀ᴗ•́)و ̑̑。
這篇也就解釋一下具體實現的思路和原理,解釋不對還請指出錯誤,解釋太長也不好,太短如果看不懂,還是看代碼多理解吧(•̀ᴗ•́)و ̑̑。
# 2017 10.8 00:06:10
code:
void BubbleSort(struct Node * head)
{
struct Node * p, * q, * tail;
tail = NULL;
while((head->next->next) != tail)
{
p = head;
q = head->next;
while(q->next != tail)
{
if((q->val) > (q->next->val))
{
p->next = q->next;
q->next = q->next->next;
p->next->next = q;
q = p->next;
}
q = q->next;
p = p->next;
}
tail = q;
}
}