深入redis内部--实现双向链表
數(shù)據(jù)結(jié)構(gòu)的應(yīng)用--Adlist.h定義
1.節(jié)點(diǎn)結(jié)構(gòu)
typedef struct listNode {
??? struct listNode *prev;? //前向節(jié)點(diǎn)
??? struct listNode *next; //后向節(jié)點(diǎn)
??? void *value;????????????? //該節(jié)點(diǎn)的值
} listNode;
2.雙向鏈表結(jié)構(gòu)
typedef struct list {
??? listNode *head;????????????? //頭節(jié)點(diǎn)
??? listNode *tail;??????????????? //尾節(jié)點(diǎn)
??? void *(*dup)(void *ptr); //復(fù)制函數(shù)
??? void (*free)(void *ptr);?? //釋放函數(shù)
??? int (*match)(void *ptr, void *key);? //匹配函數(shù),查找節(jié)點(diǎn)使用
??? unsigned long len;????????? //雙向鏈表的長度即節(jié)點(diǎn)的個(gè)數(shù)
} list;
3.雙向鏈表遍歷器
typedef struct listIter {
??? listNode *next;?? //下一個(gè)節(jié)點(diǎn)
??? int direction;
} listIter;
? 方向定義
?? #define AL_START_HEAD 0? //向前查找
?? #define AL_START_TAIL 1??? //向后查找
4.宏定義函數(shù)
#define listLength(l) ((l)->len)
#define listFirst(l) ((l)->head)
#define listLast(l) ((l)->tail)
#define listPrevNode(n) ((n)->prev)
#define listNextNode(n) ((n)->next)
#define listNodeValue(n) ((n)->value)
#define listSetDupMethod(l,m) ((l)->dup = (m))
#define listSetFreeMethod(l,m) ((l)->free = (m))
#define listSetMatchMethod(l,m) ((l)->match = (m))
#define listGetDupMethod(l) ((l)->dup)
#define listGetFree(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)
5.定義函數(shù)
list *listCreate(void); //創(chuàng)建一個(gè)新的鏈表。該鏈表可以使用AlFree()方法釋放。
????????????????????????????? //但使用AlFree()方法前需要釋放用戶釋放私有節(jié)點(diǎn)的值。
???????????????????????????? //如果沒有創(chuàng)建成功,返回null;創(chuàng)建成功則返回指向新鏈表的指針。
void listRelease(list *list);? //釋放整個(gè)鏈表,此函數(shù)不會(huì)執(zhí)行失敗。調(diào)用zfree(list *list)方法,定義在Zmalloc.c中。
list *listAddNodeHead(list *list, void *value); //向鏈表頭部中增加一個(gè)節(jié)點(diǎn)
list *listAddNodeTail(list *list, void *value);??? //向鏈表尾部增加一個(gè)節(jié)點(diǎn)
list *listInsertNode(list *list, listNode *old_node, void *value, int after);//向某個(gè)節(jié)點(diǎn)位置插入節(jié)點(diǎn) after為方向
void listDelNode(list *list, listNode *node);//從鏈表上刪除特定節(jié)點(diǎn),調(diào)用者釋放特定私用節(jié)點(diǎn)的值。
?????????????????????????????????????????????????????????? //該函數(shù)不會(huì)執(zhí)行失敗
listIter *listGetIterator(list *list, int direction);//返回某個(gè)鏈表的迭代器。
???????????????????????????????????????????????????????????????? //迭代器的listNext()方法會(huì)返回鏈表的下個(gè)節(jié)點(diǎn)。direction是方向
??????????????????????????????????????????????????????????????? //該函數(shù)不會(huì)執(zhí)行失敗。
listNode *listNext(listIter *iter);???????????????
void listReleaseIterator(listIter *iter);??????????? //釋放迭代器的內(nèi)存。
list *listDup(list *orig);?????????????????????????????? //復(fù)制整個(gè)鏈表。當(dāng)內(nèi)存溢出時(shí)返回null,成功時(shí)返回原鏈表的一個(gè)備份
?????????????????????????????????????????????????????????????? //不管該方法是否執(zhí)行成功,原鏈表不會(huì)改變。
listNode *listSearchKey(list *list, void *key);? //從特定的鏈表查找key。成功則返回第一個(gè)匹配節(jié)點(diǎn)的指針
??????????????????????????????????????????????????????????????? //如果沒有匹配,則返回null。
listNode *listIndex(list *list, long index);???? //序號(hào)從0開始,鏈表的頭的索引為0.1為頭節(jié)點(diǎn)的下個(gè)節(jié)點(diǎn)。一次類推。
??????????????????????????????????????????????????????? //負(fù)整數(shù)用來表示從尾部開始計(jì)數(shù)。-1表示最后一個(gè)節(jié)點(diǎn),-2倒數(shù)第二個(gè)節(jié)點(diǎn)
???????????????????????????????????????????????????????? //如果超過鏈表的索引,則返回null
void listRewind(list *list, listIter *li) {
??? li->next = list->head;
??? li->direction = AL_START_HEAD;
}
void listRewindTail(list *list, listIter *li) {
??? li->next = list->tail;
??? li->direction = AL_START_TAIL;
}
void listRotate(list *list);???????????????? //旋轉(zhuǎn)鏈表,移除尾節(jié)點(diǎn)并插入頭部。
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/3479342.html
總結(jié)
以上是生活随笔為你收集整理的深入redis内部--实现双向链表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hudson-ci/Using Huds
- 下一篇: 深入redis内部--实现字符串