contributed by < willy-liu >
1
根據定義
要實作list_insert_before
,就要先遍歷鏈結串列,找到before。最簡單的做法其實只需要*p
就好,實作如下
首先找到要插入的位置,然後將item->next
設定為p->next
,最後讓p->next
等於item就好。
然而,這樣的實作方式在邊界條件就會有例外,before
如果在head
就需要將l->head
取代成item
。這樣的例外就是一個不好的code smell,特別是在雙向鏈結串列,或是其他結構,如果邊界情況有好幾個時,不但會影響程式碼的閱讀,還會影響效能。
使用了**p
就可以完美解決這樣的邊界情況,將遍歷的對象從節點本身,改為在next
指標的位址上做移動,head
的型態也與next
相同,所以對p取址一次*p
就可以變更l->head
或是list_item->next
,邊界情況要做的事與一般情況的邏輯就會一致。
要實作合併排序,需要
2
3
1
2
3
AAAA
:map->bits
BBBB
:map->bits
CCCC
:first->next
DDDD
:n->pprev
EEEE
:n->pprev
Linux kernel風格的hash table架構如下
這邊注意到pprev是「指標的指標」,才可以避免發生移除節點時的例外,因為開頭的行為會與其他節點有不一致的行為