contributed by <huanginch>
此段程式碼為宣告item結構,item 包含一個數值 i 與一個嵌入至 item 的 list_head。
此段程式碼進行節點的大小比較,透過相減的方式,若 i1 的值大於 i2 會回傳正數(i1 - i2 > 0),小於回傳負數(i1 - i2 < 0),相等則回傳 0。
首先此段程式碼判斷 list 是否為 empty 或只有一個節點,是的話就直接 return (不需要 sort )。
使用 INIT_LIST_HEAD 這個巨集來產生 list_less 與 list_greater 兩個 list,分別用來儲存小於 pivot 的 list 與大於 pivot 的 list。
使用 list_first_entry 巨集從 head (也就是我們的排序目標) 取得第一個節點,並將 pivot 指向此節點。
參考 list_first_entry的說明可以得知,此巨集第二個參數需要自訂 struct 的名稱,也就是 struct item
,第三個變數為這個 struct 中 list_head
的名稱,也就是 list
。
此處 AAA 要填入 sruct item
, BBB 要填入 list
將 pivot 的 list 移走,因為在做quick sort 時,pivot 會重新連接 list_less 和 list_greater,所以舊的指向的 list 必須移除。
這段在做 quick sort 中的比大小,針對目標 list (head) 中的每個節點,如果值比 pivot 的值小就放入 list_less,大於或等於放入 list_greater。
同時依照傳入的參數來判斷,CCC使用的是 list_for_each_entry_safe
需傳入四個參數,其中前兩個分別用途為 *itm 作為 cursor、*is 用來做 temporary storage。
可參考 API文件
CCC 要填入 list_for_each_entry_safe
DDD 要填入 list_add
EEE 要填入 list_add
為了實現 stable sorting ,值與 pivot 相等的節點不能放入 list_less
考慮以下情況:
因為我們使用 head list 中的第一個節點當作 pivot,同時他的值為3,我們暫時將它稱為 ,此時 head 中第二個節點的值也是3,我們暫時稱它為,而 stable sorting 所要求的是排序後的 list 也能維持 , 的順序,因為我們排序後會依照 list_less、pivot、list_greater的順序連上,所以假設我們將等於 pviot 的值放入 list_less,會導致 , 。
這兩段程式碼有錯,這邊該執行的是遞迴呼叫 list_sort 以排序剛剛分好的兩個 list。
以上才是正確寫法。
最後將排序好的 list_less、pviot、list_greater 依照順序接上,就會得到排序好的 list。
FFF 要填入 list_splice_tail