python实现跳表SkipList的示例代码

这篇文章主要介绍了python实现跳表SkipList的示例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

python实现跳表SkipList的示例代码,恰卡网带你了解更多相关信息。

跳表

跳表,又叫做跳跃表、跳跃列表,在有序链表的基础上增加了“跳跃”的功能,由William Pugh于1990年发布,设计的初衷是为了取代平衡树(比如红黑树)。
Redis、LevelDB 都是著名的 Key-Value 数据库,而Redis中 的 SortedSet、LevelDB 中的 MemTable 都用到了跳表。
对比平衡树,跳表的实现和维护会更加简单,跳表的搜索、删除、添加的平均时间复杂度是 O(logn)。
跳表的结构如图所示:

python实现跳表SkipList的示例代码

可以发现,对于一个节点Node,其含有多个next指针,不同索引的next分别代表不同层次的下一个节点,下次是节点类Node的python定义:

class Node():     def __init__(self,key,value,level):         '''         :param level:每个node对应的nexts层数不同         '''         self.key=key         self.value=value         self.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))+"]"

关于添加、删除、查找见一下完整代码:

'''跳表 Skip List ,其初衷是为了替代红黑树'''import randomimport mkl_randomimport timeclass SkipList():    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#用于生成添加节点时的随机level        return    class Node():        def __init__(self,key,value,level):            '''            :param level:每个node对应的nexts层数不同            '''            self.key=key            self.value=value            self.nexts=[None]*level        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))+"]"    def get(self,key):        '''        :param key:        :return: key对应的value        '''        self.keyCheck(key)        node=self.__first        for level in range(self.__level - 1,-1,-1):            #在该层查找,key大于节点的key向前查找            while node.nexts[level] and node.nexts[level].key<key:                node=node.nexts[level]            if node.nexts[level] and node.nexts[level].key==key:#相等则找到,否则向下寻找                return node.nexts[level].value        return None    def put(self,key,value):        '''        return:原来的value,原来不存在key则为空        '''        self.keyCheck(key)        prev=[None]*self.__level        node=self.__first        for i in range(self.__level - 1, -1, -1):            while node.nexts[i] and node.nexts[i].key<key:                node=node.nexts[i]            if node.nexts[i] and node.nexts[i].key==key:                oldValue=node.nexts[i].value                node.nexts[i].value=value                return oldValue            prev[i]=node#保存当前level小于key的node        newLevel=self.randomLevel()        newNode=SkipList.Node(key,value,newLevel)        for i in range(newLevel):            if i<self.__level:                newNode.nexts[i]=prev[i].nexts[i]                prev[i].nexts[i]=newNode            else:                self.__first.nexts[i]=newNode        self.__size+=1        self.__level=max(self.__level, newLevel)        return None    def remove(self,key):        '''        :return: 节点对应的value值,不存在则返回None        '''        self.keyCheck(key)        prev=[None]*self.__level        node=self.__first        flag=False#该节点是否被查找到        for i in range(self.__level - 1, -1, -1):            while node.nexts[i] and node.nexts[i].key<key:                node=node.nexts[i]            if node.nexts[i].key==key:                flag=True            prev[i]=node        if not flag:            return None        removedNode=node.nexts[0]#需要被删除的节点        for i in range(len(removedNode.nexts)):#该nexts一定小于等于prev的长度            prev[i].next[i]=removedNode.nexts[i]        self.__size-=1        newLevel=self.__level        while newLevel>0 and not self.__first.nexts[newLevel - 1]:            newLevel-=1        self.__level=newLevel        return removedNode.value    def keyCheck(self, key):        '''        限制传入key不能为空        '''        if key!=0 and not key:            raise AttributeError("key can not be None")    def size(self):        return self.__size    def isEmpty(self):        return self.__size == 0    def randomLevel(self):#生成一个随机的层数        level=1        while mkl_random.rand()<self.__p and level<self.MAX_LEVEL:            level+=1        return level    def __str__(self):        result=""        for i in range(self.__level - 1, -1, -1):            result+=str(i)            node = self.__first            while node.nexts[i]:                result+=str(node.nexts[i])                node=node.nexts[i]            result+='\n'        print("level:"+str(self.__level))        return result    def showFirst(self):        for item in self.__first.nexts:            print(item,end=' ')        print()def timeCalculate(container, size:int):    begin=time.time()    for i in range(size):        if isinstance(container,dict):            container[i]= i * 3        else:            container.put(i, i * 3)    error_count = 0    for i in range(size):        if container.get(i) != i * 3:            #print("wrong " + str(i) + ":" + str(skipList.get(i)))            error_count+=1    end=time.time()    print(type(container))    print(f'error rate:{float(error_count) / size:0.5f}')    print(f'time cost:{float(end-begin)*1000:0.3f} ms')if __name__=='__main__':    timeCalculate({},1000000)    timeCalculate(SkipList(),10000)

到此这篇关于python实现跳表SkipList的文章就介绍到这了,更多相关python 跳表SkipList内容请搜索趣讯吧以前的文章或继续浏览下面的相关文章希望大家以后多多支持趣讯吧!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/3753.html

(0)
上一篇 2021-07-25 21:42:08
下一篇 2021-07-25 21:42:12

相关推荐

  • 20年前国足赢阿曼(今晚能再胜吗 究竟是什么情况?)

    20年前国足赢阿曼今晚能再胜吗究竟是什么情况?!黄健翔说道:“20年前的世预赛十强赛,中国队第一个客场在阿曼首都马斯喀特2-0击败对手,当时上半场0-0,下半场范志毅罚进杨璞制造的点球,祁宏打入另一粒球,国足2-0拿下阿曼,在头两场比赛

    2021-11-11
    20
  • 散文的作文600字初中(初中优美散文600字)

    又一个清晨,我从网吧赶回去。一到班级,班头就叫我出去。“奇怪,我最近没怎么呀?上课没迟到,作业及时完成,难道是?……”班头笑眯眯地上下打量着我。好一会,我实在忍不住了便问:“老师,,有什么事快说,我还要读书呢?”,“小子,不错有发展前途,竟赛得了市

    2022-01-14
    20
  • 微博会员怎么取消自动续费(微博会员有什么用)

    今天中午12点46分,收到支付宝短信通知:在新浪微博成功付款5.70元。这个点我正在睡觉呢,没进行任何操作,怎么会有支付发生呢?真是有点不知所措!经仔细查看新浪微博和支付宝,原来是我的新浪微博绑定了支付宝,并且上个月不小心开通了微博会员的自动续费服务

    2022-01-14 热点头条
    30
  • 歼?10C首秀(第三代战机空战能力再提升)

    歼-10C首秀!第三代战机空战能力再提升在第十三届中国航展上,我国自主研发的第三代改进型超音速多用途战斗机歼-10C,首次以静态展示的方式参展。此次中国航展上展出的歼-10

    2021-10-02 热点头条
    40
  • 江苏扬州疫情什么时候结束(2021扬州疫情最新消息)

    从目前的疫情情况来看,国内扬州的疫情算是比较严峻的,每日也是出现了本土病例,并且危重症病例比较多,那么江苏扬州疫情什么时候结束,2021扬州疫情最新消息是怎么样,接下来大家就随久久派小编一起了解看看~江苏扬州疫情什么时候结束据官方最新疫情通报,7月28日至8月7日,扬州全市累计报告本土确诊病例308例,其中轻型72例,普通型211例,重型19例,危重型6例

    2021-08-09
    20
  • 拥有上古血脉的姓氏(上古八大姓最尊贵的)

    姓氏是一种历史文化现象,是一个家族血缘关系的标志和符号,有的家族姓氏很普通,有的家族姓氏很尊贵,那么拥有上古血脉的姓氏是什么?上古八大姓最尊贵的是那几个?下面就跟久久派小编来了解一下吧!拥有上古血脉的姓氏第一位姬姓对于姓氏文化稍微有点了解的人都知道,这才

    2021-09-13
    40

发表回复

登录后才能评论