python怎么实现跳表SkipList
python怎么实现跳表SkipList
本篇内容介绍了“python怎么实现跳表SkipList”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
跳表
跳表,又叫做跳跃表、跳跃列表,在有序链表的基础上增加了“跳跃”的功能,由William Pugh于1990年发布,设计的初衷是为了取代平衡树(比如红黑树)。
Redis、LevelDB 都是著名的 Key-Value 数据库,而Redis中 的 SortedSet、LevelDB 中的 MemTable 都用到了跳表。
对比平衡树,跳表的实现和维护会更加简单,跳表的搜索、删除、添加的平均时间复杂度是 O(logn)。
跳表的结构如图所示:
可以发现,对于一个节点Node,其含有多个next指针,不同索引的next分别代表不同层次的下一个节点,下次是节点类Node的python定义:
classNode():def__init__(self,key,value,level):""":paramlevel:每个node对应的nexts层数不同"""self.key=keyself.value=valueself.nexts=[None]*level#节点类型next指针,初始值为空def__str__(self):#return"[key:"+str(self.key)+",value:"+str(self.value)+"len:"+str(len(self.nexts))+"]"return"["+str(self.key)+","+str(self.value)+","+str(len(self.nexts))+"]"
关于添加、删除、查找见一下完整代码:
"""跳表SkipList,其初衷是为了替代红黑树"""importrandomimportmkl_randomimporttimeclassSkipList():def__init__(self):#头节点不存储任何数据self.MAX_LEVEL=32#最大level层数self.__first=SkipList.Node(None,None,self.MAX_LEVEL)#头节点self.__level=0#实际的level层数self.__size=0#Jiedian个数self.__p=0.25#用于生成添加节点时的随机levelreturnclassNode():def__init__(self,key,value,level):""":paramlevel:每个node对应的nexts层数不同"""self.key=keyself.value=valueself.nexts=[None]*leveldef__str__(self):#return"[key:"+str(self.key)+",value:"+str(self.value)+"len:"+str(len(self.nexts))+"]"return"["+str(self.key)+","+str(self.value)+","+str(len(self.nexts))+"]"defget(self,key):""":paramkey::return:key对应的value"""self.keyCheck(key)node=self.__firstforlevelinrange(self.__level-1,-1,-1):#在该层查找,key大于节点的key向前查找whilenode.nexts[level]andnode.nexts[level].key<key:node=node.nexts[level]ifnode.nexts[level]andnode.nexts[level].key==key:#相等则找到,否则向下寻找returnnode.nexts[level].valuereturnNonedefput(self,key,value):"""return:原来的value,原来不存在key则为空"""self.keyCheck(key)prev=[None]*self.__levelnode=self.__firstforiinrange(self.__level-1,-1,-1):whilenode.nexts[i]andnode.nexts[i].key<key:node=node.nexts[i]ifnode.nexts[i]andnode.nexts[i].key==key:oldValue=node.nexts[i].valuenode.nexts[i].value=valuereturnoldValueprev[i]=node#保存当前level小于key的nodenewLevel=self.randomLevel()newNode=SkipList.Node(key,value,newLevel)foriinrange(newLevel):ifi<self.__level:newNode.nexts[i]=prev[i].nexts[i]prev[i].nexts[i]=newNodeelse:self.__first.nexts[i]=newNodeself.__size+=1self.__level=max(self.__level,newLevel)returnNonedefremove(self,key):""":return:节点对应的value值,不存在则返回None"""self.keyCheck(key)prev=[None]*self.__levelnode=self.__firstflag=False#该节点是否被查找到foriinrange(self.__level-1,-1,-1):whilenode.nexts[i]andnode.nexts[i].key<key:node=node.nexts[i]ifnode.nexts[i].key==key:flag=Trueprev[i]=nodeifnotflag:returnNoneremovedNode=node.nexts[0]#需要被删除的节点foriinrange(len(removedNode.nexts)):#该nexts一定小于等于prev的长度prev[i].next[i]=removedNode.nexts[i]self.__size-=1newLevel=self.__levelwhilenewLevel>0andnotself.__first.nexts[newLevel-1]:newLevel-=1self.__level=newLevelreturnremovedNode.valuedefkeyCheck(self,key):"""限制传入key不能为空"""ifkey!=0andnotkey:raiseAttributeError("keycannotbeNone")defsize(self):returnself.__sizedefisEmpty(self):returnself.__size==0defrandomLevel(self):#生成一个随机的层数level=1whilemkl_random.rand()<self.__pandlevel<self.MAX_LEVEL:level+=1returnleveldef__str__(self):result=""foriinrange(self.__level-1,-1,-1):result+=str(i)node=self.__firstwhilenode.nexts[i]:result+=str(node.nexts[i])node=node.nexts[i]result+=""print("level:"+str(self.__level))returnresultdefshowFirst(self):foriteminself.__first.nexts:print(item,end="")print()deftimeCalculate(container,size:int):begin=time.time()foriinrange(size):ifisinstance(container,dict):container[i]=i*3else:container.put(i,i*3)error_count=0foriinrange(size):ifcontainer.get(i)!=i*3:#print("wrong"+str(i)+":"+str(skipList.get(i)))error_count+=1end=time.time()print(type(container))print(f"errorrate:{float(error_count)/size:0.5f}")print(f"timecost:{float(end-begin)*1000:0.3f}ms")if__name__=="__main__":timeCalculate({},1000000)timeCalculate(SkipList(),10000)
“python怎么实现跳表SkipList”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注恰卡编程网网站,小编将为大家输出更多高质量的实用文章!
推荐阅读
-
python多行注释符号怎么表示
python多行注释符号怎么表示这篇文章主要介绍“python多行...
-
python支持的操作系统是什么
python支持的操作系统是什么这篇文章主要介绍“python支持...
-
python如何判断列表为空
python如何判断列表为空这篇文章主要介绍“python如何判断...
-
Python如何利用D3Blocks绘制可动态交互的图表
-
2021年度编程语言揭晓
-
PPython:PHP 拥抱 Python 的利器
-
哪种Python IDE最适合你?这里有一份优缺点列表
-
Python分隔字符串函数用法split
aaa,bbb=str.split(‘&&’,2)第一个参数为分隔符第二个参数是要完成的最大拆分数...
-
php安全编程——python测试实例编写
-
神奇的Python模块:pdfkit,将Python抓取的网址内容保存pdf文件