python 점프 표 SkipList 구현 예제 코드

메타제
점프 표 는 점프 표,점프 리스트 라 고도 부 르 는데 질서 있 는 링크 를 바탕 으로'점프'기능 을 추 가 했 고 William Pugh 가 1990 년 에 발표 했다.디자인 의 취 지 는 균형 트 리(예 를 들 어 빨 간 검 은 나무)를 대체 하기 위해 서 이다.
Redis,LevelDB 는 모두 유명한 Key-Value 데이터베이스 이 고 Redis 의 SortedSet,LevelDB 의 MemTable 은 모두 점프 표를 사용 했다.
밸 런 스 트 리 에 비해 점프 표 의 실현 과 유지 가 더욱 간단 합 니 다.점프 표 의 검색,삭제,추 가 된 평균 시간 복잡 도 는 O(logn)입 니 다.
점프 표 의 구 조 는 그림 과 같다.
在这里插入图片描述
한 노드 노드 노드 에 대해 여러 개의 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 random

import mkl_random
import time

class 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+='
' 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 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기