typedef
struct listnode listnode;
雙端鍊錶節點包含2個指標域和1個資料域,注意資料的型別為void*,因此其可以承載任意資料型別。
typedef
struct list list;
雙端鍊錶中,使用函式指標來封裝與節點值相關的操作,在後面的使用中較頻繁,並維護乙個len作為鍊錶長度,而不需要每次求長度時都進行遍歷。
鍊錶的建立很簡單,就是建立乙個list指標,為其分配記憶體,然後將其中的指標域全部置為null,len則置為0。鍊錶的釋放如下:
void
listrelease
(list *list)
// 釋放鍊錶結構
zfree
(list)
;}
在釋放的過程中,通過判斷len是否為零來進行迴圈釋放。
鍊錶插入新節點分為頭部插入、尾部插入和中間插入。此處只給出中間插入的**,因為頭部和尾部插入都很簡單,只需要根據鍊錶是否為空,分兩種情況進行插入即可。
list *
listinsertnode
(list *list, listnode *old_node,
void
*value,
int after)
// 將新節點新增到給定節點之前
}else
}// 更新新節點的前置指標
if(node-
>prev !=
null
)// 更新新節點的後置指標
if(node-
>next !=
null
)// 更新鍊錶節點數
list-
>len++
;return list;
}
從上述插入過程可以看出,沒有進行只拷貝,只是簡單的指標賦值,顯然待插入的資料value必須保證在鍊錶存在期間都不能被釋放,否則造成指標懸掛。
void
listdelnode
(list *list, listnode *node)
使用迭代器可以方便的去遍歷鍊錶結構,其中direction表示迭代器的前進方向。
typedef
struct listiter listiter;
建立迭代器操作如下:
listiter *
listgetiterator
(list *list,
int direction)
迭代器遍歷過程如下:
listnode *
listnext
(listiter *iter)
return current;
}
list *
listdup
(list *orig)
}else
value = node-
>value;
// 將節點新增到鍊錶if(
listaddnodetail
(copy, value)
==null)}
// 釋放迭代器
listreleaseiterator
(iter)
;// 返回副本
return copy;
}
如果鍊錶有設定值複製函式 dup ,那麼對值的複製將使用複製函式進行,否則,新節點將和舊節點共享同乙個指標。而無論複製是成功還是失敗,輸入節點都不會被修改。
listnode *
listsearchkey
(list *list,
void
*key)
}else}}
listreleaseiterator
(iter)
;// 未找到
return
null
;}
對比操作由鍊錶的 match 函式負責進行, 如果沒有設定 match 函式, 那麼直接通過對比值的指標來決定是否匹配。 如果匹配成功,那麼第乙個匹配的節點會被返回。如果沒有匹配任何節點,那麼返回 null 。
void
listrotate
(list *list)
取出鍊錶的表尾節點,並將它移動到表頭,成為新的表頭節點。 LinkedList原始碼解析之鍊錶結構
單鏈表與雙鏈表的結構圖 單向鍊錶 class node 雙向鍊錶 class node linkedlist採用的是雙向鍊錶 linkedlist的add 方法 public boolean add e e void linklast e e linkedlist的get 方法 public e g...
redis0 1原始碼解析之鍊錶
分析 之前先看看鍊錶的資料結構。新建乙個煉表頭結點 list listcreate void 釋放乙個鍊錶 void listrelease list list 釋放鍊錶記憶體 zfree list 3 插入乙個節點 支援頭插和尾插 給鍊錶新增乙個節點,頭插法 list listaddnodehea...
鍊錶結構解析 linux原始碼
在linux核心 中,經常會使用到鍊錶結構,其中分為普通鍊錶和雜湊表。普通鍊錶在檔案list.h中,定義的格式如下 struct list head 其中比較難理解的地方有兩點 1 如何通過在資料結構中新增list head成員變數實現鍊錶 2 如何通過list head成員變數訪問宿主資料 關於第...