參照了Redis里面的雙鏈表結構,可以說是完全復制粘貼,redis的雙鏈表還是寫的很通俗易懂的,沒有什么花里胡哨的東西,但是redis還有個iter迭代器的結構來遍歷鏈表,我這里就沒有實作了,只是實作了雙鏈表的基本操作
redis雙鏈表結構有如下特點
- 多型:可以儲存多種資料型別
- 雙端
- 無環:也就是說head->pre==NULL tail->next=NULL
- 帶有長度計數器
- 有頭指標和尾指標
實作
注意,這里的鏈表有一個迭代器結構,方便遍歷鏈表
#include<iostream>
#include<stdlib.h>
using namespace std;
#define START_HEAD 0
#define START_TAIL 1
struct listNode{
listNode* prev;
listNode* next;
int value; //可以是void void*型別 實作多型鏈表
};
struct list{
listNode* head;
listNode* tail;
int len;
};
//迭代器模式
typedef struct listIter {
listNode *next;
int direction; //遍歷方向
};
//創建迭代器
listIter *listGetIterator(list *myList, int direction)
{
listIter *iter = (listIter*)malloc(sizeof(listIter));
if (direction == START_HEAD)
iter->next = myList->head;
else
iter->next = myList->tail;
iter->direction = direction;
return iter;
}
/* Release the iterator memory */
void listReleaseIterator(listIter *iter) {
free(iter);
}
//將迭代器指向開頭節點
void listRewind(list *myList, listIter *li) {
li->next = myList->head;
li->direction = START_HEAD;
}
//迭代器指向尾部節點
void listRewindTail(list *myList, listIter *li) {
li->next = myList->tail;
li->direction = START_TAIL;
}
//用迭代器遍歷下一個節點
listNode *listNext(listIter *iter)
{
listNode *current = iter->next;
if (current != NULL) {
if (iter->direction == START_HEAD)
iter->next = current->next;
else
iter->next = current->prev;
}
return current;
}
//初始化鏈表
list* listCreate(){
list* myList;
myList = (list*)malloc(sizeof(list));
myList->head = myList->tail=NULL;
myList->len=0;
return myList;
}
//移除鏈表元素
void listEmpty(list* list){
int len = 0;
listNode* current,*next;
current = list->head;
while(len--){
next = current->next;
free(current);
current = next;
}
list->head=list->tail=NULL;
list->len=0;
}
void listRelease(list* list){
listEmpty(list);
free(list);
list = NULL;
}
//頭插
list* listAddNodeHead(list* list,int val){
listNode* node = (listNode*)malloc(sizeof(listNode));
node->value = https://www.cnblogs.com/biningooginind/p/val;
if(list->len==0){
list->head = list->tail=node;
node->prev=node->next=NULL;
}else{
node->prev = NULL;
node->next = list->head;
list->head->prev = node;
list->head = node;
}
list->len++;
return list;
}
//尾插
list* listAddNodeTail(list* myList,int val){
listNode* node = (listNode*)malloc(sizeof(listNode));
node->value = val;
if(myList->len==0){
myList->head = myList->tail = node;
node->prev=node->next=NULL;
}else{
node->prev = myList->tail;
myList->tail->next = node;
node->next=NULL;
myList->tail = node;
}
myList->len++;
return myList;
}
//插入到指定節點前面或后面
list* listInsertNode(list* list,listNode* old_node,int val,bool after){
listNode* node = (listNode*)malloc(sizeof(listNode));
node->value = val;
if(after){
node->prev = old_node;
node->next = old_node->next;
if(list->tail==old_node){
list->tail = node;
}
}else{
node->next = old_node;
node->prev = old_node->prev;
if(list->head==old_node){
list->head = node;
}
}
if(node->prev!=NULL){
node->prev->next = node;
}
if(node->next!=NULL){
node->next->prev = node;
}
list->len++;
return list;
}
//洗掉指定節點
void listDelNode(list* list,listNode* node){
if(node->prev)
node->prev->next = node->next;
else //是頭節點
list->head = node->next;
if(node->next) //如果不是尾節點
node->next->prev = node->prev;
else
list->tail = node->prev;
free(node);
node = NULL;
list->len--;
}
//鏈表的復制
list* listCopy(list* old_list){
list* new_list = listCreate();
listNode* node;
listIter iter;
listRewind(old_list,&iter); //指向開頭節點
while((node=listNext(&iter))!=NULL){
listAddNodeTail(new_list,node->value);
}
//listRelease(old_list);
return new_list;
}
//根據值查找節點
listNode* listSearchKey(list* myList,int val){
listNode* node;
listIter iter;
listRewind(myList,&iter);
while((node=listNext(&iter))!=NULL && node->value!=val)
;
if(node)
return node;
else
return NULL;
}
//根據索引查找節點 支持倒排序索引
listNode* listIndex(list* list,int index){
listNode* node;
if(index<0){
index = (-index)-1;
node = list->tail;
while(index-- && node) node =node->prev;
}
else{
node = list->head;
while(index-- && node) node = node->next;
}
return node;
}
//second連接到first
list* listJoin(list* first,list* second){
if(second->head)
second->head->prev = first->tail;
if(first->tail)
first->tail->next = second->head;
else //first鏈表是空的
first->head = second->head;
if(second->tail)
first->tail = second->tail;
first->len +=second->len;
second->head = second->tail = NULL;
second->len = 0;
return first;
}
#define dlist_for_each(pos, head) /
for (pos = (head)->next; pos != NULL; pos = pos->next)
#define dlist_reverse_for_each(pos, head) /
for (pos = (head)->next; pos!=NULL; pos = pos->next)
void Show_Int_List(list* myList){
listNode* node;
dlist_for_each(node,myList->head){
cout<value<value<len<
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/69630.html
標籤:其他
上一篇:演算法與資料結構(3):基本資料結構——鏈表,堆疊,佇列,有根樹
下一篇:字典
