前言
本問題出自於 jserv - Linux 核心設計講座 第一周 linked list 和非連續記憶體操作 底下題目一的延伸題目

在這篇文章會紀錄關於 bubble sort 的實現。
node 結構
|
|
本題目 linked list 屬於 circular doubly linked list, 所以處理上還需要考慮循環的問題。
swap 之後要把 node 的 prev 跟 next pointer 處理好。
Bubble sort
|
|
在寫 linked list 版本的 sort 之前,先來看一下一般 array 版本的實現方式。
基本上 bubble sort 算是一個容易理解的演算法,現在比較大的問題是要先實現一個 swap 來對兩個 node 交換。
swap_node
|
|
因為我們 linked list 是採用 doubly linked list,所以還要額外處理 prev 指標。
以下用簡單的示意圖解釋一下這個 swap 是怎麼運作的

今天我們想要 swap node_2, node_3,經過 swap 之後應該要變成這樣:

先複習一下我們 swap function 的定義
|
|
所以我們傳入的是 node_2, node_3 的地址,node_1, node_4 則不能直接存取。
接著我們一步一步來解析,先處理 node_1, node_3 之間的連結
|
|
因為我們沒辦法直接存取 node_1,所以要透過 node_2->prev 來表示
|
|

接著處理 node_2, node_4 之間的連結
|
|
因為我們無法直接存取 node_4, 所以要表示成 node_3->next;
|
|
處理完之後變成這樣,最後只需要處理 node_2, node_3 之間的連結

讓 node_2->prev 指向 node_3, node_3->next 指向 node2,實現最後的交換。
|
|
最後完成如下

建議如果對指標不熟悉的最好自己拿紙筆畫一次,會清楚很多。
Bubble sort with Circular doubly linked list
|
|
接著來介紹 bubble sort 在 circular doubly linked list 中的實現
根據剛剛 array 版本的 bubble sort,我們需要兩個指標指向要比較的兩點。
|
|
跟一般的 bubble sort 實現原理基本相同,只是因為我們的資料結構是 circular doubly linked list,所以有幾個需要注意的地方
|
|
繼續用剛剛的例子,假設今天是 node_2, node_3 要交換
此時 lnode 指向 node_2, rnode 指向 node_3

交換完之後會變成

這時候為了後續的交換,需要把 lnode, rnode 指向正確的地方
才需要這段程式碼
|
|

傳統的 bubble sort 每一輪比完都要從 arr[0] 開始重新比較,在 circular doubly linked list 中,我們每輪結束都要把 lnode 重新指向起點,並將 rnode 指向 lnode->next。
|
|
完整的程式碼放在 GitHub
之後也會補上延伸題目的 merge sort。