Redis鍊錶(adlist) 含原始碼

2021-09-26 05:51:31 字數 4702 閱讀 9152

鍊錶作為經典且常用的資料結構,在很多高階程式語言中都內建了鍊錶這種資料額結構,但是redis是有c語言實現,並沒有內建這種資料結構,所以redis自身構建了鍊錶。

節點和鍊錶的實現

listnode結構表示為:

typedef

struct listnode listnode;

節點的定義是很簡單的,這些簡單的定義足以滿足鏈節點的需求

list的定義:

typedef

struct list list;

下圖展示由3個listnode組成的list

redis鍊錶特性:

關於鍊錶的一些原始碼

redis鍊錶這部分算是比較簡單的,原始碼中一些api的實現的**也容易看懂。以下對一些原始碼做一些簡單的說明,不感興趣的可以不看。

listiter:

typedef

struct listiter listiter;

#define al_start_head 0

#define al_start_tail 1

實現乙個鍊錶的迭代器,是為了方便的遍歷整個鍊錶。direction的值取為al_start_head或者al_start_tail,分別代表從頭部開始遍歷,及從尾部遍歷。比如說當directional_start_head時,next跟listnode中的next值相同,當directional_start_tail時,nextlistnode中的prev值相同。

listcreate

list *

listcreate

(void

)

建立並初始化乙個鍊錶。可用alfreelist()函式釋放建立的鍊錶。但是呼叫alfreelist()之前需要釋放每個節點。

listempty

void

listempty

(list *list)

list->head = list->tail =

null

; list->len =0;

}

清空整個鍊錶但不破壞鍊錶本省,從head開始,通過鍊錶長度len迭代釋放節點。

listrelease

void

listrelease

(list *list)

釋放整個鍊錶

listaddnodehead

list *

listaddnodehead

(list *list,

void

*value)

else

list->len++

;// 增加鍊錶長度

return list;

}

為乙個元素申請乙個節點,並新增到鍊錶最前端。出錯時,返回null並且不執行任何操作(即鍊錶保持不變)。成功時,返回傳遞給函式的list指標。

listaddnodetail

list *

listaddnodetail

(list *list,

void

*value)

else

list->len++

;return list;

}

方法和listaddnodehead一樣,listaddnodetail將節點新增到最末端。

listinsertnode

list *

listinsertnode

(list *list, listnode *old_node,

void

*value,

int after)

}else

}// 更新鍊錶節點關係

if(node->prev !=

null)if

(node->next !=

null

) list->len++

;return list;

}

為乙個元素建立節點,並插入在指定節點前或者指定節點後。after引數來控制節點插入的位置,after為0則插入在指定節點前,after為非0則插入在指定節點後。

listdelnode

void

listdelnode

(list *list, listnode *node)

從鍊錶當中刪除指定的乙個節點。

listgetiteratorlistreleaseiteratorlistrewindlistrewindtaillistnext

listiter *

listgetiterator

(list *list,

int direction)

/* release the iterator memory */

void

listreleaseiterator

(listiter *iter)

/* create an iterator in the list private iterator structure */

void

listrewind

(list *list, listiter *li)

void

listrewindtail

(list *list, listiter *li)

listnode *

listnext

(listiter *iter)

return current;

}

listnode:返回迭代器的下乙個元素。 使用listdelnode()刪除當前返回的元素是有效的,但不刪除其他元素。該函式返回指向列表下乙個元素的指標,如果沒有更多元素,則返回nulllistdup

list *

listdup

(list *orig)

}else

value = node->value;if(

listaddnodetail

(copy, value)

==null)}

return copy;

}

複製整個列表。 在記憶體不足時返回null。成功時,將返回原始列表的副本。

listsearchkey

listnode *

listsearchkey

(list *list,

void

*key)

}else}}

return

null

;}

在列表中搜尋與給定鍵匹配的節點。成功時,返回第乙個匹配的節點指標(從頭開始搜尋)。 如果不存在匹配節點,則返回null。

listindex

listnode *

listindex

(list *list,

long index)

else

return n;

}

返回指定的從零開始的索引處的元素,其中0是頭部,1是頭部旁邊的元素,依此類推。 使用負整數以便從尾部計數,-1是最後乙個元素,-2是倒數第二個,依此類推。 如果索引超出範圍,則返回null。

listrotate

void

listrotate

(list *list)

旋轉列表,刪除尾節點並將其插入頭部

listjoin

void

listjoin

(list *l, list *o)

在列表』l』的末尾新增列表』o』的所有元素。 列表』o』置為空,但有效。

Redis原始碼學習 雙向鍊錶adlist

鍊錶結點中儲存兩個指標,分別指向前後,還有乙個void 指標指向儲存的資料 typedef struct listnode listnode 鍊錶,包含兩個鍊錶節點指標,乙個指向head,乙個指向tail 其中dup函式指標指向兩個鍊錶拷貝時對鍊錶節點value的拷貝方法。match為尋找鍊錶中和k...

Redis 鍊錶

定義 每個鍊錶節點使用乙個 adlist.h listnode 結構來表示 typedef struct listnode listnode adlist.h list 列表結構 typedef struct list list 特性 redis 的鍊錶實現的特性可以總結如下 雙端 鍊錶節點帶有 p...

鍊錶之鍊表含環,相交等問題

兩個鍊錶,可能相交,找出相交的節點,給出證明 1.若兩個單鏈表乙個為有環,乙個無環.那麼肯定不能相交.2.若二者都沒有環,問題就轉化為 兩個無環單鏈表是否相交,是否能找到第乙個相交的節點,方法就是 快慢指標 3.若二者都有環,那麼問題變成了兩個有環單鏈表是否相交.第一,先找到二者是否相交.第二,若相...