在Redis的双链表实现的基本结构:

1。节点结构



typedef struct思路:{
结构思路:沪指 / / *转发节点;
结构思路: / / *下;对节点
空值*;节点值
思路:};





2。双向链表结构


定义列表{
思路:*头; / /头节点
思路:*尾巴; / /尾节点
void *(* DUP)(void *ptr); / /复制功能
无效的(自由)(void *ptr); / /释放功能
Int(比赛)(void *ptr,void *键); / /匹配功能,搜索结
无符号长整型数;节点长度双向链表数
列表};




三.双向链表ergodicer


listiter { typedef struct
思路:*下; / /下一个节点
int方向;
listiter };

方向的定义

#定义al_start_head 0 / /向前搜索
#定义al_start_tail / / 1向后搜寻




4。宏定义功能



#定义listlength(L)((L)-> Len)
#定义listfirst(L)((L)->头)
#定义listlast(L)((L)->尾)
#定义listprevnode(N)((N)->沪指)
#定义listnextnode(N)((N)->下一步)
#定义listnodevalue(N)((N)->价值)

#定义listsetdupmethod(L,M)(L)-> DUP =(M))
#定义listsetfreemethod(L,M)(L)->自由=(M))
#定义listsetmatchmethod(L,M)(L)->匹配=(M))

#定义listgetdupmethod(L)((L)-> DUP)
#定义listgetfree(L)((L)->免费)
#定义listgetmatchmethod(L)((L)->匹配)




5。定义函数


列表listcreate(void); / /创建一个新的列表,列表可以发布使用AlFree()方法。

但使用alfree / /()需要释放用户释放私人节点值的方法。

如果没有成功,则返回null;创建的指针成功返回到新列表。


无效listrelease(名单列表); / /发布的名单,这个函数不执行失败,zfree(名单列表)方法,在zmalloc定义C.


listaddnodehead列表(列表清单,void*值); / /将节点添加到列表中的头


listaddnodetail列表(列表清单,void*值); / /将节点添加到列表的结尾


listinsertnode列表(列表清单,思路:* old_node,void*值后,int); / /一个节点插入节点后的方向


无效listdelnode(列表清单,思路:*节点); / /删除特定的节点列表,私人发布具体的节点值。

此函数不执行失败。
listiter * listgetiterator(列表清单,int方向); / /返回一个列表迭代器。

(listnext) / /迭代器方法返回一个列表的下一个节点。方向是方向

此函数不执行失败。


思路:* listnext(listiter *iter);


无效listreleaseiterator(listiter *iter); / /释放迭代器的记忆。


listdup列表(列表*原价); / /列表的副本。返回null时内存溢出,并返回原来的备份链表成功时

不管方法是否成功,原始列表不会更改。


思路:* listsearchkey(列表清单,void *键); / /从列表中查找特定的关键。成功返回第一个匹配的节点的指针

如果没有匹配,则返回null。


思路:*列表索引(列表清单,长指数); / /序号从0开始,对索引列表的头0.1的下一个节点的第一个节点。一类的类比。

用于表示从尾部开始计数的负整数。- 1表示最后一个节点,第2个倒数第二个节点。

如果超过一个列表的索引返回null


无效listrewind(列表的列表,listiter *李){
李-下一个;
李->方向= al_start_head;
}

无效listrewindtail(列表的列表,listiter *李){
李;
李->方向= al_start_tail;
}


无效listrotate(名单列表); / /旋转列表,删除和插入头尾节点。






链表结构和结构的思路:API

列表和思路:有自己的家庭的API。在这里,我想了解一下Redis的源代码。下面的代码是基于redis,可直接编译运行通过Redis。

列表listcreate(void)



*创建一个新列表
*
**(1)
* /
列表listcreate(void)
{
列表;

用于分发列表结构的内存
列表=(结构表*)malloc(sizeof(struct列表));
如果(list = NULL)
返回null;

初始化属性
列表>;
列表> > = 0;
列表-> DUP = null;
列表> >空=空;
列表>匹配= null;

返回列表;
}






无效listrelease(名单列表)





*释放整个清单
*
* o(n),n作为列表长度
* /
无效listrelease(名单列表)
{
无符号长透镜;
思路:*,*下;

电流=列表;
=列表;

而(镜头){
下一个=当前>下一个;
如果列表是免费的,则节点值调用它。
如果(列表>空闲)列表> >空闲(当前- >值);
在发布节点
自由(电流);
当前=下一个;
}
免费(名单);
}



listaddnodehead列表(列表清单,void*值)



*创建一个给定值的新节点,并将其添加到表头
*
**(1)
* /
listaddnodehead列表(列表清单,void*值)
{
思路:*结;

节点=(思路:*)malloc(sizeof(思路:));
如果(节点= NULL)
返回null;

节点>值=值;

如果(列表> = = 0){
第一个节点
列表>;
节点->进程节点->下= null;
{人}
/不是第一个节点
节点-> prev = null;
节点>下一个;
列表->头->进程节点;
列表>头=节点;
}

列表>;

返回列表;
}






listaddnodetail列表(列表清单,void*值)



*创建一个给定值的新节点,并将其添加到列表的结尾
*
**(1)
* /
listaddnodetail列表(列表清单,void*值)
{
思路:*结;

节点=(思路:*)malloc(sizeof(思路:));
如果(节点= NULL)
返回null;

如果(列表> = = 0){
第一个节点
列表>;
节点->进程节点->下= null;
{人}
/不是第一个节点
节点->进程列表->尾;
节点> >下一个=空;
列表>尾-下一个=节点;
列表>尾=节点;
}

列表>;

返回列表;
}






listinsertnode列表(列表清单,思路:* old_node,void*值,int后)





*创建包含值值的节点
之前或之后的old_node *和插入新的节点,通过在参数显示
*
**(1)
* /
listinsertnode列表(列表清单,思路:* old_node,void*值,int后)
{
思路:*结;

节点=(思路:*)malloc(sizeof(思路:));
如果(节点= NULL)
返回null;

如果(后){
插入 / / old_node
节点-> prev = old_node;
节点->下= old_node ->下;
表/尾节点
如果(列表->尾= = old_node){
列表>尾=节点;
}
{人}
插入old_node / /前
节点->下= old_node;
节点-> prev = old_node ->沪指;
处理头节点
如果(列表->头= = old_node){
列表>头=节点;
}
}

指针更新前节点和后继节点(这个地方非常经典,保存代码)
如果(节点->沪指!= NULL){
节点->上->下一组节点;
}
如果(节点>下一个!= NULL){
节点->下->进程节点;
}

更新列表节点
列表>;

返回列表;
}





无效listdelnode(列表清单,思路:*节点)





*发布列表中的给定节点
*
**(1)
* /
无效listdelnode(列表清单,思路:*节点)
{
/前体节点指针处理
如果(节点->沪指){
节点->上->下=节点->下;
{人}
列表>头=节点>下一个;
}

处理节点
如果(节点>下一个){
节点->下->进程节点->沪指;
{人}
列表->尾=节点->沪指;
}

发布/节点值
如果(列表>空闲)列表> >空闲(节点>值);

发布/节点
空闲(节点);

更新列表节点号
列表>—;
}





迭代器

事实上,我对迭代器的概念很奇怪,因为我是一个纯粹的C程序员,不是C++,这里遵循的研究!

Redis实现链表结构迭代器,用于遍历链表

迭代器的结构定义如下:



*列表迭代器
* /
listiter { typedef struct
下一个节点
思路:*下;

迭代方向
int方向;
listiter };






方向确定下一步的指针或迭代器迭代遍历沿prev指针,它可以al_start_head常数或adlist al_start_tail常数。H.


#定义al_start_head 0
#定义al_start_tail 1






学习迭代器的API实现:

listiter * listgetiterator(列表清单,int方向)



*创建列表列表的迭代器,迭代方向由参数方向决定。
*
*每一次迭代的迭代器listnext(),迭代器返回的列表中的下一个节点
*
**(1)
* /
listiter * listgetiterator(列表清单,int方向)
{
listiter *iter++;

ITER =(listiter *)malloc(sizeof(listiter));
如果(= NULL)
返回null;

根据迭代器的方向,即指向页眉或页脚的迭代器指针
如果(方向= = al_start_head){
下一个列表;
{人}
下一个列表;
}

记录/方向
方向=方向;

返回ITER;
}






无效listrewind(列表的列表,listiter *李)



迭代器到迭代列表的头指针
*
**(1)
* /
无效listrewind(列表的列表,listiter *李)
{
李-下一个;
李->方向= al_start_head;
}






无效listrewindtail(列表的列表,listiter *李)



*表的迭代器迭代器迭代指针列表
*
**(1)
* /
无效listrewindtail(列表的列表,listiter *李)
{
李;
李->方向= al_start_tail;
}






思路:* listnext(listiter *iter)



*函数要么返回当前节点,要么返回null,所以通常使用的是:
* ITER = listgetiterator(列表);
*在(((节点= listnext(ITER))!= NULL){
* dosomethingwith(listnodevalue(结));
* }
*
**(1)
* /
思路:* listnext(listiter *iter)
{
思路:*电流= ITER ->下;

如果(当前!= NULL){
根据迭代方向选择节点
如果(ITER ->方向= al_start_head)
下一个;
其他的
ITER ->下=电流>沪指;
}

返回电流;
}