亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數(shù)據(jù)庫 > Redis > 正文

詳解Redis中的雙鏈表結構

2020-10-28 21:40:16
字體:
來源:轉載
供稿:網(wǎng)友

Redis中雙鏈表實現(xiàn)的基本結構:
1.節(jié)點結構

typedef struct listNode {  struct listNode *prev; //前向節(jié)點  struct listNode *next; //后向節(jié)點  void *value;       //該節(jié)點的值} listNode;

2.雙向鏈表結構

typedef struct list {  listNode *head;       //頭節(jié)點  listNode *tail;        //尾節(jié)點  void *(*dup)(void *ptr); //復制函數(shù)  void (*free)(void *ptr);  //釋放函數(shù)  int (*match)(void *ptr, void *key); //匹配函數(shù),查找節(jié)點使用  unsigned long len;     //雙向鏈表的長度即節(jié)點的個數(shù)} list;

3.雙向鏈表遍歷器

typedef struct listIter {  listNode *next;  //下一個節(jié)點  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)建一個新的鏈表。該鏈表可以使用AlFree()方法釋放。               //但使用AlFree()方法前需要釋放用戶釋放私有節(jié)點的值。               //如果沒有創(chuàng)建成功,返回null;創(chuàng)建成功則返回指向新鏈表的指針。void listRelease(list *list); //釋放整個鏈表,此函數(shù)不會執(zhí)行失敗。調用zfree(list *list)方法,定義在Zmalloc.c中。list *listAddNodeHead(list *list, void *value); //向鏈表頭部中增加一個節(jié)點list *listAddNodeTail(list *list, void *value);  //向鏈表尾部增加一個節(jié)點list *listInsertNode(list *list, listNode *old_node, void *value, int after);//向某個節(jié)點位置插入節(jié)點 after為方向void listDelNode(list *list, listNode *node);//從鏈表上刪除特定節(jié)點,調用者釋放特定私用節(jié)點的值。                              //該函數(shù)不會執(zhí)行失敗listIter *listGetIterator(list *list, int direction);//返回某個鏈表的迭代器。                                 //迭代器的listNext()方法會返回鏈表的下個節(jié)點。direction是方向                                //該函數(shù)不會執(zhí)行失敗。listNode *listNext(listIter *iter);        void listReleaseIterator(listIter *iter);      //釋放迭代器的內存。list *listDup(list *orig);                //復制整個鏈表。當內存溢出時返回null,成功時返回原鏈表的一個備份                                //不管該方法是否執(zhí)行成功,原鏈表不會改變。listNode *listSearchKey(list *list, void *key); //從特定的鏈表查找key。成功則返回第一個匹配節(jié)點的指針                                //如果沒有匹配,則返回null。listNode *listIndex(list *list, long index);   //序號從0開始,鏈表的頭的索引為0.1為頭節(jié)點的下個節(jié)點。一次類推。                            //負整數(shù)用來表示從尾部開始計數(shù)。-1表示最后一個節(jié)點,-2倒數(shù)第二個節(jié)點                             //如果超過鏈表的索引,則返回nullvoid 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);         //旋轉鏈表,移除尾節(jié)點并插入頭部。

list結構和listNode結構的API
list和listNode都有它們自己的一族API,這里貼出來學習一下redis的源碼(ps:下面的代碼都是我仿照redis改寫能直接編譯運行的代碼)

list *listCreate(void)

  /**    * 創(chuàng)建一個新列表    *    * T = O(1)                                                                  */   list *listCreate(void)   {     struct list *list;        // 為列表結構分配內存     list = (struct list *)malloc(sizeof(struct list));     if (list == NULL)       return NULL;        // 初始化屬性     list->head = list->tail = NULL;     list->len = 0;     list->dup = NULL;     list->free = NULL;     list->match = NULL;        return list;   } 


void listRelease(list *list)

 

  /**    * 釋放整個列表    *    * T = O(N), N為列表長度    */   void listRelease(list *list)   {     unsigned long len;     listNode *current, *next;        current = list->head;     len = list->len;        while (len --) {       next = current->next;       // 如果列表有自帶的free方法,那么先對節(jié)點值調用它       if (list->free) list->free(current->value);       // 之后釋放節(jié)點       free(current);       current = next;     }     free(list);   }  

list *listAddNodeHead(list *list, void *value)
  /**    * 新建一個包含給定value的節(jié)點,并將它加入到列表的表頭    *    * T = O(1)                                                                  */   list *listAddNodeHead(list *list, void *value)   {     listNode *node;        node = (listNode *)malloc(sizeof(listNode));     if (node == NULL)       return NULL;        node->value = value;        if (list->len == 0) {       // 第一個節(jié)點       list->head = list->tail = node;       node->prev = node->next = NULL;     } else {       // 不是第一個節(jié)點       node->prev = NULL;       node->next = list->head;       list->head->prev = node;       list->head = node;     }        list->len ++;        return list;   } 


list *listAddNodeTail(list *list, void *value)

  /**    * 新建一個包含給定value的節(jié)點,并把它加入到列表的表尾    *    * T = O(1)    */   list *listAddNodeTail(list *list, void *value)   {     listNode *node;          node = (listNode *)malloc(sizeof(listNode));     if (node == NULL)       return NULL;        if (list->len == 0) {       // 第一個節(jié)點       list->head = list->tail = node;       node->prev = node->next = NULL;     } else {       // 不是第一節(jié)點       node->prev = list->tail;       node->next = NULL;       list->tail->next = node;       list->tail = node;     }        list->len ++;        return list;   } 


list *listInsertNode(list *list, listNode *old_node, void *value, int after)

 

  /**    * 創(chuàng)建一個包含值value的節(jié)點    * 并根據(jù)after參數(shù)的指示,將新節(jié)點插入到old_node的之前或者之后    *    * T = O(1)    */   list *listInsertNode(list *list, listNode *old_node, void *value, int after)   {     listNode *node;        node = (listNode *)malloc(sizeof(listNode));     if (node == NULL)       return NULL;        if (after) {       // 插入到old_node之后       node->prev = old_node;       node->next = old_node->next;       // 處理表尾節(jié)點       if (list->tail == old_node) {         list->tail = node;       }     } else {       // 插入到old_node之前       node->next = old_node;       node->prev = old_node->prev;       // 處理表頭節(jié)點       if (list->head == old_node) {         list->head = node;       }     }        // 更新前置節(jié)點和后繼節(jié)點的指針(這個地方很經(jīng)典,節(jié)約代碼)     if (node->prev != NULL) {       node->prev->next = node;     }     if (node->next != NULL) {       node->next->prev = node;     }        // 更新列表節(jié)點     list->len ++;        return list;   } 


void listDelNode(list *list, listNode *node)

  

 /**    * 釋放列表中給定的節(jié)點    *    * T = O(1)    */   void listDelNode(list *list, listNode *node)   {     // 處理前驅節(jié)點指針     if (node->prev) {       node->prev->next = node->next;     } else {       list->head = node->next;     }        // 處理后繼節(jié)點     if (node->next) {       node->next->prev = node->prev;     } else {       list->tail = node->prev;     }        // 釋放節(jié)點值     if (list->free) list->free(node->value);        // 釋放節(jié)點     free(node);        // 更新列表節(jié)點數(shù)目     list->len --;   } 


迭代器
其實我對迭代器的概念非常陌生,因為我是純c程序員,不會c++,這里直接跟著學了!

Redis針對list結構實現(xiàn)了一個迭代器,用于對鏈表進行遍歷

迭代器的結構定義如下:

  /**    * 鏈表迭代器    */   typedef struct listIter {     // 下一節(jié)點     listNode *next;        // 迭代方向     int direction;   } listIter; 


direction決定了迭代器是沿著next指針向后迭代,還是沿著prev指針向前迭代,這個值可以是adlist.h中的AL_START_HEAD常量或AL_START_TAIL常量:

  #define AL_START_HEAD 0   #define AL_START_TAIL 1 


學習一下迭代器的api實現(xiàn):

listIter *listGetIterator(list *list, int direction)

  /**    * 創(chuàng)建列表list的一個迭代器,迭代方向由參數(shù)direction決定    *    * 每次對迭代器listNext(),迭代器返回列表的下一個節(jié)點    *    * T = O(1)    */   listIter *listGetIterator(list *list, int direction)   {     listIter *iter;        iter = (listIter *)malloc(sizeof(listIter));     if (iter == NULL)       return NULL;        // 根據(jù)迭代器的方向,將迭代器的指針指向表頭或者表尾     if (direction == AL_START_HEAD) {       iter->next = list->head;     } else {       iter->next = list->tail;     }        // 記錄方向     iter->direction = direction;        return iter;   } 


void listRewind(list *list, listIter *li)

  /**    * 將迭代器iter的迭代指針倒回list的表頭    *    * T = O(1)    */   void listRewind(list *list, listIter *li)   {     li->next = list->head;     li->direction = AL_START_HEAD;   } 


void listRewindTail(list *list, listIter *li)

  /**    * 將迭代器iter的迭代指針倒回list的表尾    *    * T = O(1)    */   void listRewindTail(list *list, listIter *li)   {     li->next = list->tail;     li->direction = AL_START_TAIL;   } 


listNode *listNext(listIter *iter)

  /**    * 函數(shù)要么返回當前節(jié)點,要么返回NULL,因此,常見的用法是:    * iter = listGetIterator(list, <direction>);    * while ((node = listNext(iter)) != NULL) {    *   doSomethingWith(listNodeValue(node));    * }    *    * T = O(1)    */   listNode *listNext(listIter *iter)   {     listNode *current = iter->next;        if (current != NULL) {       // 根據(jù)迭代方向,選擇節(jié)點       if (iter->direction == AL_START_HEAD)         iter->next = current->next;       else         iter->next = current->prev;     }        return current;   } 

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
丰满的少妇愉情hd高清果冻传媒| 影音先锋资源av| 亚洲国产欧美一区二区三区不卡| 亚洲天堂视频网站| 国产精品入口麻豆免费观看| 日本孕妇大胆孕交无码| 18一19gay欧美视频网站| 欧美激情一区二区三区成人| 欧美老女人bb| 99热国内精品| 黄网站在线观看高清免费| 日韩视频一区在线观看| 在线视频观看亚洲| 自拍视频网站| 99热这里只有精品2| xxxxx欧美| 久久综合中文字幕| 亚洲免费av观看| 成人av电影免费观看| 国产成人免费av一区二区午夜| 亚洲精品一区av在线播放| 国产乱子伦三级在线播放| 五月天综合网站| 国产精品视频你懂的| 这里只有久久精品| 国产精品天干天干在线综合| 国产精华7777777| 欧美丝袜丝交足nylons图片| 亚洲香蕉伊在人在线观| 久久99中文字幕| 日韩视频专区| 无码免费一区二区三区免费播放| 欧美性色黄大片手机版| 国产精品99免费看| 欧美韩一区二区| 亚洲日本va中文字幕久久| 亚洲va韩国va欧美va精四季| 无码国产精品高潮久久99| 国产在线69| youjizz欧美| 91免费国产视频网站| 操女生的网站| 成人免费看黄网址| 国产中文字幕视频在线观看| 日韩av高清在线播放| 精品一区二区久久久久久久网站| 性欧美freesex顶级少妇| 中日韩免视频上线全都免费| 91青娱乐在线视频| 91麻豆精品国产91久久综合| 午夜一级毛片| 免费在线观看一区二区三区| 深夜福利国产精品| 日韩欧美网站| 成年女人免费v片| 国产精久久久| 伊人精品一区二区三区| 欧美人在线视频| 在线成人av网站| 免费一级在线观看播放网址| 欧美a在线播放| 国产一区二区三区高清播放| 日本美女一级片| 激情欧美成人久久综合小说| 欧美激情videos| 成人网在线免费视频| 亚洲免费视频观看| 不用播放器成人网| 最新黄色网址在线观看| 无码av免费精品一区二区三区| 中文字幕不卡在线| 成人在线爆射| 外国成人在线视频| 成人做爰69片免费| 国内外成人在线视频| 青草在线视频| 最新一本之道波多野结衣| 男人午夜天堂| 高清成人在线观看| 四虎成人精品在永久在线观看| 亚洲乱码中文字幕综合| 日本成人精品| 91精品啪在线观看国产81旧版| www.亚洲免费| 国产三级精品三级在线观看国产| 男女污污视频网站| 黄视频网站在线看| 91伊人久久大香线蕉| 国产无精乱码一区二区三区| 国产最新视频在线观看| 国产奶水涨喷在线播放| 日韩最新av| 精品999在线播放| 青青草成人在线观看| 久久免费视频99| 日本精品一区二区| 亚洲综合欧美激情| 小早川怜子久久精品中文字幕| 欧美日韩视频在线播放| 久久久99免费视频| 亚洲视频重口味| 99久久99久久久精品棕色圆| 91精品国产91久久久久久吃药| av首页在线观看| 国产三级日本三级在线播放| 国产成人精品无码免费看夜聊软件| 91麻豆精品在线| 国产伦精品一区二区三区免| 中国美女黄色一级片| 欧美一区二区三区四区在线观看地址| 你懂的在线免费观看| 中文在线免费视频| 国产一区二区区别| 秋霞欧美一区二区三区视频免费| 伊人久久av导航| 亚洲一区二区三区无码久久| 亚洲人成网站色在线观看| 欧美性猛交xxxx久久久| 国产精品第七影院| 九色在线观看视频| 色狼人综合干| 国产精品一卡二卡三卡| 一本色道久久hezyo无码| 精品亚洲一区二区三区四区五区高| 麻豆网站在线免费观看| 一区二区欧美国产| 亚洲一级免费视频| 51国偷自产一区二区三区的来源| 91视频91自| 日韩大片免费观看视频播放| 久久综合伊人77777麻豆| a级大片在线观看| 亚洲国产欧美国产第一区| 性欧美精品高清| 精品中文字幕不卡在线视频| 成人3d动漫一区二区三区| 欧美特级一级片| www.日韩.com| 久久久久九九精品影院| 99视频只有精品| 欧美aⅴ99久久黑人专区| 亚洲永久精品在线观看| 激情小说综合网| 在线亚洲欧美专区二区| 日本v片在线免费观看| 国产亚洲精品aa午夜观看| 国产免费av高清在线| www国产在线| 一女三黑人理论片在线| 91九色精品| 亚洲777理论| 自拍偷拍欧美专区| 欧美精品久久久久久久久老牛影院| 中文字幕第36页| 91在线看视频| 国产精品久久久久久影视| 成人无码av片在线观看| 日韩在线视频观看| 国产区美女在线| 四虎在线看片| 欧美激情精品久久久久久小说| 日韩三级精品电影久久久| 成人在线观看视频网站| 精品国产一区一区二区三亚瑟| 国产又大又黄又粗又爽| 欧美mv日韩mv国产网站app| 国产一区二区三区免费| 5g国产欧美日韩视频| 久久久久久久久久久久久女过产乱| 成人av在线一区二区三区| 欧美在线视频免费播放| 无码无套少妇毛多18pxxxx| 欧美性猛交xxx乱大交3蜜桃| 日韩国产欧美在线视频| 蜜桃久久精品一区二区| 国产精品国产三级在线观看| 成人精品鲁一区一区二区| 美女禁区视频免费观看精选| 男女啪啪无遮挡| 欧美丰满美乳xxx高潮www| 国产jzjzjz丝袜老师水多| 欧美一级爱爱| 欧美伊人久久久久久午夜久久久久| 成人黄色大片在线免费观看| 国产嫩草在线观看| 成人一区二区| 精品国产一区在线| 国产精品调教视频| 欧美日韩国产123区| 手机在线成人av| 日韩美女一区二区三区四区| 成人在线亚洲| 欧美日韩国产在线观看| 天天操天天干天天爽| 91网页在线观看| 黄色av电影在线播放| 日韩三级电影免费观看| 欧美成人黄色小视频| 亚洲在线成人| 欧美一级做一级爱a做片性| 欧美日精品一区视频| 亚洲免费成人av| 乱子伦在线视频| 国产精品久久久久久亚洲调教| 欧美一a一片一级一片| 亚洲精品资源在线| 成人免费视频视频| 久久久久免费精品国产| 日韩不卡在线视频| 国产视频精品在线| 亚洲欧洲精品天堂一级| 久久久99久久精品欧美| 午夜精彩国产免费不卡不顿大片| 欧美国产欧美亚州国产日韩mv天天看完整| 精品盗摄一区二区三区| 91麻豆蜜桃一区二区三区| 亚洲资源网你懂的| 国产18无套直看片| 激情伦成人综合小说| 米奇精品关键词| 日韩激情av在线播放| 老司机精品视频在线| 日韩经典一区二区| 波多野结衣中文字幕久久| 九九九久久国产免费| 91精品综合视频| 欧美日韩视频精品一区二区| 日韩精品视频无播放器在线看| 国产一卡二卡三卡| 在免费jizzjizz在线视频| 午夜欧美福利视频| 亚洲成人国产| 生活片a∨在线观看| 一区二区三区自拍| 成人在线观看视频网站| 亚洲欧美资源在线| 久久久久亚洲AV成人| 精品免费视频一区二区| 秋霞av在线| 国产三区精品| 日韩高清一区二区| 日本精品视频| 亚洲一区二区三区免费在线观看| 高清不卡一区| 领导边摸边吃奶边做爽在线观看| 日本最黄视频| 69av视频在线| 午夜久久一区| 影院在线观看全集免费观看| 亚洲色欲色欲www在线观看| 在线免费av播放| 中文字幕一区二区三区手机版| 狠狠色狠狠色综合日日小说| 久久发布国产伦子伦精品| 图片区小说区区亚洲五月| 日本一区二区在线播放| av成人资源网| 黄色的视频在线免费观看| 国产精品最新| 欧美做爰爽爽爽爽爽爽| av官网在线观看| 中文字幕线观看| 欧美 日韩 国产 在线观看| 国产羞羞视频| av亚洲在线观看| 91精品国产高清久久久久久91裸体| 国产成人亚洲综合小说区| av人人综合网| 国产亚洲毛片| 97久久国产亚洲精品超碰热| www.91popny.com| 99久久久国产精品无码网爆| 午夜精品久久久久久久99黑人| 一区二区三区四区国产| 日韩av免费在线播放| 91九色网站| 亚洲欧洲成人av每日更新| 9久久9毛片又大又硬又粗| 精品无码国产污污污免费网站| 永久免费黄色片| 亚洲国产精品一区二区尤物区| 精品无吗乱吗av国产爱色| 欧美视频免费| 日本一区二区精品| 国产精品久久久久久久久借妻| 国外av网站| 草草视频在线免费观看| 欧美色图五月天| 亚洲精品免费在线视频| 毛片.com| 亚洲精品动漫久久久久| 日韩美女精品在线| 高清在线观看日韩| 国产激情视频一区二区在线观看| 精品国产视频在线观看| 久久成人综合网| www..com.cn蕾丝视频在线观看免费版| 欧美日韩你懂得| 在线电影国产精品| 久久亚洲精品网站| 偷拍亚洲色图| 一个人看的www在线免费视频| 91在线小视频| 91成人在线网站| 国产精品啊v在线| 99久久夜色精品国产亚洲96| 麻豆影视在线播放| 亚洲精品久久| 成人久久久精品乱码一区二区三区| 国产精品玖玖玖在线资源| av麻豆国产| 国产精品一区二区久久不卡| 欧美大交乱xxxxxbbb| 亚洲国产日韩欧美在线图片| 欧美黄色高清视频| 翔田千里一区二在线观看| 97在线资源在| 日韩中文字幕一区二区高清99| 亚洲国产精品电影在线观看| 精品伊人久久久| 日韩欧美在线1卡| 色诱女教师一区二区三区| 蜜桃极品自拍av| 久久精品久久综合| 国产精品电影网站| 日韩中文字幕久久| 久久99精品国产99久久| 黄色网页在线免费观看|