五月综合激情婷婷六月,日韩欧美国产一区不卡,他扒开我内裤强吻我下面视频 ,无套内射无矿码免费看黄,天天躁,日日躁,狠狠躁

新聞動態(tài)

python實現(xiàn)跳表SkipList的示例代碼

發(fā)布日期:2022-02-22 08:59 | 文章來源:CSDN

跳表

跳表,又叫做跳躍表、跳躍列表,在有序鏈表的基礎上增加了“跳躍”的功能,由William Pugh于1990年發(fā)布,設計的初衷是為了取代平衡樹(比如紅黑樹)。
Redis、LevelDB 都是著名的 Key-Value 數(shù)據(jù)庫,而Redis中 的 SortedSet、LevelDB 中的 MemTable 都用到了跳表。
對比平衡樹,跳表的實現(xiàn)和維護會更加簡單,跳表的搜索、刪除、添加的平均時間復雜度是 O(logn)。
跳表的結構如圖所示:

可以發(fā)現(xiàn),對于一個節(jié)點Node,其含有多個next指針,不同索引的next分別代表不同層次的下一個節(jié)點,下次是節(jié)點類Node的python定義:

class Node():
  def __init__(self,key,value,level):
'''
:param level:每個node對應的nexts層數(shù)不同
'''
self.key=key
self.value=value
self.nexts=[None]*level#節(jié)點類型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):
  #頭節(jié)點不存儲任何數(shù)據(jù)
  self.MAX_LEVEL = 32  # 最大level層數(shù)
  self.__first=SkipList.Node(None, None, self.MAX_LEVEL)#頭節(jié)點
  self.__level=0#實際的level層數(shù)
  self.__size=0#Jiedian個數(shù)
  self.__p=0.25#用于生成添加節(jié)點時的隨機level
  return
 class Node():
  def __init__(self,key,value,level):
'''
:param level:每個node對應的nexts層數(shù)不同
'''
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大于節(jié)點的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#保存當前l(fā)evel小于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: 節(jié)點對應的value值,不存在則返回None
  '''
  self.keyCheck(key)
  prev=[None]*self.__level
  node=self.__first
  flag=False#該節(jié)點是否被查找到
  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]#需要被刪除的節(jié)點
  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):#生成一個隨機的層數(shù)
  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實現(xiàn)跳表SkipList的文章就介紹到這了,更多相關python 跳表SkipList內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持本站!

海外服務器租用

版權聲明:本站文章來源標注為YINGSOO的內(nèi)容版權均為本站所有,歡迎引用、轉載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內(nèi)容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。

相關文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務

7x24全年不間斷在線

專屬顧問服務

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務熱線

關注
微信

關注官方微信
頂部