数码资讯
在Redis的双链表结构的详细解释
在Redis的双链表实现的基本结构: 1。节点结构 typedef struct思路:{ 结构思路:沪指 / / *转发节点; 结构思路: / / *下;对节点 空值*;节点值 思路:}; 2。双向链表结构 定义列表{ 思路:*头; / /头节点 思路:*尾巴; / /尾节点 void *(* DU
选购提示
关注价格、性能、续航、售后和真实使用场景,理性比较后再下单。
在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 ->下=电流>沪指;
}
返回电流;
}
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 ->下=电流>沪指;
}
返回电流;
}
声明:本文内容用于数码产品信息整理与选购参考,具体价格、库存、售后政策以官方渠道和电商页面实时信息为准。