python怎么实现redis双链表
python怎么实现redis双链表
这篇文章主要介绍“python怎么实现redis双链表 ”,在日常操作中,相信很多人在python怎么实现redis双链表 问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python怎么实现redis双链表 ”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
redis 双链表
特点:
len: O(1),获取链表长度
head: O(1), 头部第一个节点
tail: O(1) 尾部第一个节点
无环: 非循环链表
void *: 存储任意类型数据。 (动态语言天然自带)
2.双链表API接口
创建/销毁/初始化:
listCreate
listEmpty
listRelease
添加节点/删除节点:
listAddNodeHead
listAddNodeTail
listInsertNode
listDelNode
实现迭代器/正向/反向遍历:
listGetIterator
listReleaseIterator
listRewind
listRewindTail
listNext
list复制,查找,旋转合并操作:listDup
listSearchKey
listIndex
listRotateTailToHead
listRotateHeadToTail
listJoin
源码
3.使用python实现redis双链表的api
参考redis list定义节点和DLinkList
python动态语言需要手动管理内存申请释放.
使用生成器, 偷懒式实现正向反向遍历.
"""参考redisadlist.c.实现双链表相关的apiheadtailNone<-<-<-123->->->Nonelen:3"""importcopyfromtypingimportAnyclassNode(object):def__init__(self,data)->None:self.next=Noneself.pre=Noneself.data=datadef__str__(self)->str:returnf"{self.data}"classDLinkList(object):def__init__(self)->None:self.head=Noneself.tail=Noneself.len=0defempty(self)->None:self.head=Noneself.tail=Noneself.len=0defadd_node_head(self,data=None)->Node:"""[头插法]Args:data([type],optional):[description].DefaultstoNone."""new_node=Node(data=data)ifself.len==0:#链表为空.处理头/尾指针self.tail=new_nodeself.head=new_nodeelse:#插入新节点new_node.next=self.headself.head.pre=new_nodeself.head=new_nodeself.len+=1returnnew_nodedefadd_node_tail(self,data:Any=None)->Node:"""[尾插法]Args:data([type],optional):[description].DefaultstoNone."""new_node=Node(data=data)ifself.len==0:#链表为空.处理头/尾指针self.tail=new_nodeself.head=new_nodeelse:#插入新节点new_node.pre=self.tailnew_node.next=self.tail.nextself.tail.next=new_node#更新尾指针self.tail=new_nodeself.len+=1returnnew_nodedefinsert_node(self,old_node:Node=None,data:Any=None,after:bool=False)->None:"""[插入新节点,在旧节点的前/后]Args:old_node(Node,optional):[旧节点].DefaultstoNone.data(Any,optional):[新数据].DefaultstoNone.after(Bool,optional):[是否在之后插入].DefaultstoFalse."""assertself.len,f"self.len({self.len})must>0"new_node=Node(data=data)ifafter:new_node.pre=old_nodenew_node.next=old_node.nextold_node.next.pre=new_nodeold_node.next=new_nodeifself.tail==old_node:self.tail=new_nodeelse:new_node.pre=old_node.prenew_node.next=old_nodeold_node.pre.next=new_nodeold_node.pre=new_nodeifself.head==old_node:self.head=new_nodeself.len+=1defdel_node(self,node:Node)->None:"""[删除节点]Args:node(Node):[description]"""assertself.len,"DLinklistisNone"ifnotnode:returnifnode==self.head:self.head=node.nextelse:#1.处理nextnode.pre.next=node.nextifnode==self.tail:self.tail=node.preelse:#2.处理prenode.next.pre=node.prenode.pre=Nonenode.next=Nonedelnodeself.len-=1defnext(self,reversed:bool=False):"""[获取生成器]Args:reversed(bool,optional):[description].DefaultstoFalse.Returns:[type]:[description]"""ifreversed:returnself._reverse_next()returnself._next()def_reverse_next(self):"""[反向迭代,使用生成器记录状态]Yields:[type]:[description]"""cur=self.tailidx=self.len-1whilecur:yield(idx,cur)idx-=1cur=cur.predef_next(self):"""[正向迭代,使用生成器记录状态]]Yields:[type]:[description]"""cur=self.headidx=0whilecur:yield(idx,cur)idx+=1cur=cur.nextdefdup(self):returncopy.deepcopy(self)deffind(self,key:Any=None)->tuple:ifnotkey:returng=self.next()foridx,nodeing:ifnode.data==key:returnidx,nodereturn-1,Nonedefrotate_tail_to_head(self)->None:"""[正向旋转节点]移动尾节点,插入到头部"""assertself.len>=2,"dlistlenmust>=2"head=self.headtail=self.tail#removetailself.tail=tail.preself.tail.next=None#movetoheadtail.next=headtail.pre=head.preself.head=taildefrotate_head_to_tail(self)->None:"""[反向旋转节点]移动头点,插入到尾部"""assertself.len>=2,"dlistlenmust>=2"head=self.headtail=self.tail#removeheadself.head=head.nextself.head.pre=None#movetotailtail.next=headhead.pre=tailself.tail=headself.tail.next=Nonedefjoin(self,dlist:Any=None):"""[合并双链表]Args:dlist(Any,optional):[description].DefaultstoNone."""passdef__str__(self)->str:ans=""foridx,nodeinself.next(reversed=False):ans+=f"idx:({idx})data:({node.data})n"returnansdeftest_add_node(dlist:DLinkList=None):n=5foriinrange(n):dlist.add_node_tail(data=i)#dlist.add_node_head(data=i)print(dlist)deftest_del_node(dlist:DLinkList=None):i=dlist.lenwhilei:node=Nonedlist.del_node(node)i-=1print(dlist)deftest_insert_node(dlist:DLinkList=None):#dlist.insert_node(old_node=old_node,data=100,after=True)#print(dlist,id(dlist))#nlist=dlist.dup()#print(nlist,id(nlist))idx,fnode=dlist.find(1)print('findnode:',idx,fnode)dlist.insert_node(fnode,100,after=True)print("insertafter")print(dlist)dlist.insert_node(fnode,200,after=False)print("insertbefore")print(dlist)deftest_rotate(dlist:DLinkList=None):print("moveheadtotail")dlist.rotate_head_to_tail()print(dlist)print("movetailtohead")dlist.rotate_tail_to_head()print(dlist)deftest_join(dlist:DLinkList=None,olist:DLinkList=None):print("joinlist")nlist=dlist.join(olist)print(nlist)defmain():dlist=DLinkList()test_add_node(dlist)#test_del_node(dlist)#test_insert_node(dlist)test_rotate(dlist)if__name__=="__main__":main()
到此,关于“python怎么实现redis双链表 ”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注恰卡编程网网站,小编会继续努力为大家带来更多实用的文章!
推荐阅读
-
python(中无效的十进制怎么解决 python怎么转换进制)
python怎么转换进制?Python执行二进制转换:1.十进制到二进制(bin)首先,让让我们看看如何将十进制转换成二进制。我...
-
python怎么清除完全相同的行(python splte如何分隔有多个相同符号的str)
pythonsplte如何分隔有多个相同符号的str?str你的string内容str_(相同的符号)执行完了以后再在相同符号的...
-
python(编程控制电脑关机 如何控制电脑关机)
如何控制电脑关机?可以在电脑的运行窗口中输入输入公式,给电脑可以设置自动关机。1.按开快捷键winr然后打开运行窗口。2.在运行窗...
-
python中的特殊标识符(python 中 标识符中可以有逗号吗)
python中标识符中可以有逗号吗?在python语言中合法的标识符是字母、数字以及_,所以我合法的标识符中肯定不能有逗号if...
-
python(excel 提取数据写入新表 python导入excel数据找不到工作簿)
python导入excel数据找不到工作簿?我可以导入数据后找不到工作,不是因为他的工作没有被转移。什么软件可提取并合并Exce...
-
python中字典定义的四种方法(python global关键字的用法详解)
pythonglobal关键字的用法详解?global标志实际上是目的是提示python讲解器,说被其修饰的变量是全局变量。这样...
-
python(array用法 python如何对两个数组做差处理)
python如何对两个数组做差处理?Python中的列表中的元素肯定不能真接相加,减。t最佳的位置的是将列表装换成Python中的...
-
php如何让Swoole/Pool进程池实现Redis持久连接
php如何让Swoole/Pool进程池实现Redis持久连接本篇...
-
python多行注释符号怎么表示
python多行注释符号怎么表示这篇文章主要介绍“python多行...
-
python支持的操作系统是什么
python支持的操作系统是什么这篇文章主要介绍“python支持...