赞
踩
from collections import deque class TreeNode: def __init__(self,data,left=None,right=None): self.data=data self.left=left self.right=right #迭代:o(n),o(n) n:节点个数 def preOrder(root:TreeNode): if root is None: return [] res,stack=[],[] stack.append(root) while len(stack): curr=stack.pop() res.append(curr.data) if curr.right: stack.append(curr.right) if curr.left: stack.append(curr.left) return res #递归:o(n),o(n)(最好o(nlogn)) def preOrderR(root:TreeNode): res=[] def preOrder(node): if node is None: return res.append(node.data) preOrder(node.left) preOrder(node.right) preOrder(root) return res #迭代:o(n),o(n) n:节点个数 def inOrder(root:TreeNode): if root is None: return [] res,stack=[],[] curr=root while curr or len(stack): while curr: stack.append(curr) curr=curr.left node=stack.pop() res.append(node.data) curr=node.right return res #递归:o(n),o(n)(最好o(nlogn)) def inOrderR(root:TreeNode): res = [] def inOrder(node): if node is None: return inOrder(node.left) res.append(node.data) inOrder(node.right) inOrder(root) return res #迭代:o(n),o(n) n:节点个数 def postOrder(root:TreeNode): if root is None: return [] res,stack=[],[] #根->右->左 stack.append(root) while len(stack): curr=stack.pop() res.append(curr.data) if curr.left: stack.append(curr.left) if curr.right: stack.append(curr.right) #左->右->根 res.reverse() return res #递归:o(n),o(n)(最好o(nlogn)) def postOrderR(root:TreeNode): res=[] def postOrder(node): if node is None: return [] postOrder(node.left) postOrder(node.right) res.append(node.data) postOrder(root) return res #方法1(一维数组):o(n),o(n) def levelOrder_1(root:TreeNode): if root is None: return [] #队列queue res,queue=[],deque() queue.append(root) while len(queue): #key:每轮循环遍历处理一个节点 curr=queue.popleft() res.append(curr.data) #将遍历节点的左右子节点入队 if curr.left: queue.append(curr.left) if curr.right: queue.append(curr.right) return res #方法2(二维数组):o(n),o(n) def levelOrder_2(root: TreeNode): if root is None: return [] # 队列queue res,queue=[],deque() queue.append(root) while len(queue): size,level_nodes=len(queue),[] #key:每轮循环遍历处理一层节点 for i in range(size): curr=queue.popleft() level_nodes.append(curr.data) # 将遍历节点的左右子节点入队 if curr.left: queue.append(curr.left) if curr.right: queue.append(curr.right) res.append(level_nodes) return res if __name__=='__main__': root=TreeNode(23) node1=TreeNode(34) node2=TreeNode(21) node3=TreeNode(99) node4=TreeNode(77) node5=TreeNode(90) node6=TreeNode(45) node7=TreeNode(60) root.left=node1 root.right=node2 node1.left=node3 node3.left=node4 node3.right=node5 node2.left = node6 node2.right = node7 print(preOrder(root)) print(preOrderR(root)) print(inOrder(root)) print(inOrderR(root)) print(postOrder(root)) print(postOrderR(root)) print(levelOrder_1(root)) print(levelOrder_2(root))
class TreeNode: def __init__(self, data, left=None, right=None): self.data = data self.left = left self.right = right class BST: def __init__(self, __comp): self.root = None self.size = 0 self.__comp = __comp def getSize(self): return self.size def isEmpty(self): return self.size == 0 # 插入:o(logn) def add(self, e): if self.root is None: self.root = TreeNode(e) else: curr = self.root while curr: # 比较 if self.__comp(e, curr.data) == 0: return elif self.__comp(e, curr.data) < 0 and not curr.left: curr.left = TreeNode(e) self.size += 1 return elif self.__comp(e, curr.data) > 0 and not curr.right: curr.right = TreeNode(e) self.size += 1 return if self.__comp(e, curr.data) < 0: curr = curr.left else: curr = curr.right # 修改o(logn):set(src,target)会破坏二叉搜索树的顺序 #查询 def contains(self, target): node = self.find(target) if not node: return False return True #O(logn) def find(self, target): if not self.root: return None curr = self.root while curr: if self.__comp(target, curr.data) == 0: return curr elif self.__comp(target, curr.data) < 0: curr = curr.left else: curr = curr.right return None # 中序遍历:方便观察结果,找bug def inOrder(self): res = [] def inOrderR(node): if not node: return [] inOrderR(node.left) res.append(node.data) inOrderR(node.right) inOrderR(self.root) return res #O(logn) def minValue(self): if not self.root: raise Exception("tree is null") min_node = self.root while min_node.left: #最深最左 min_node = min_node.left return min_node.data #O(logn) def maxValue(self): if not self.root: raise Exception("tree is null") max_node = self.root while max_node.right: #最深最右 max_node = max_node.right return max_node.data #删除 #O(logn) def removeMin(self): if not self.root: raise Exception("tree is null") # 找 min_node, parent = self.root, None while min_node.left: parent = min_node min_node = min_node.left #删 if not parent: #位于根节点处 self.root = self.root.right else: #key parent.left = min_node.right min_node.right = None self.size -= 1 return min_node.data # 时间复杂度:O(logn) def removeMax(self): if not self.root: raise Exception("tree is null") # 找 max_node, parent = self.root, None while max_node.right: parent = max_node max_node = max_node.right #删 if not parent: #位于根节点处 self.root = self.root.left else: parent.right = max_node.left max_node.left = None self.size -= 1 return max_node.data #优化: O(logn) def remove_2(self, e): if not self.root: return #找 curr, parent = self.root, None while curr and self.__comp(e, curr.data) != 0: parent = curr if self.__comp(e, curr.data) < 0: curr = curr.left else: curr = curr.right # 如果没有找到需要删除的元素,则直接返回 if not curr: return #情况简化 if curr.left and curr.right: #找右子树最小值 min_node, min_parent = curr.right, curr while min_node.left: min_parent = min_node min_node = min_node.left #覆盖该删除节点值 curr.data = min_node.data #curr变为叶子节点:情况则简化成三种 curr, parent = min_node, min_parent #确定开删节点是仅有一个子树节点还是叶子节点 if curr.left: child = curr.left #if parent: #curr.left = None elif curr.right: child = curr.right #if parent: #curr.right = None else: child = None #开删 if not parent: self.root = child elif curr == parent.left: parent.left = child elif curr == parent.right: parent.right = child self.size -= 1 #o(logn) def remove_1(self, e): if not self.root: return curr, parent = self.root, None # 找 while curr and self.__comp(e, curr.data) != 0: parent = curr if self.__comp(e, curr.data) < 0: curr = curr.left else: curr = curr.right # 如果没有找到需要删除的元素,则直接返回 if not curr: return # 删 if not curr.left and not curr.right: if not parent: self.root = None elif curr == parent.left: parent.left = None elif curr == parent.right: parent.right = None elif curr.left and not curr.right: if not parent: self.root = curr.left elif curr == parent.left: parent.left = curr.left curr.left = None elif curr == parent.right: parent.right = curr.left curr.left = None elif not curr.left and curr.right: if not parent: self.root = curr.right elif curr == parent.left: parent.left = curr.right curr.right = None elif curr == parent.right: parent.right = curr.right curr.right = None elif curr.left and curr.right: #找右子树最小值 min_node, min_parent = curr.right, curr while min_node.left: min_parent = min_node min_node = min_node.left ##覆盖该删除节点值 curr.data = min_node.data #覆盖该删除节点值 # 先拿到要删除 min 节点的右子树 right = min_node.right # bug 修复:这里删除 min 节点,需要区分 min 是父亲节点的右子节点还是左子节点 # 要删除 min 节点是父亲节点的右子节点 if min_parent.right == min_node: """ 比如我们要删除以下树的节点70 33 / \ 22 66 / \ 35 70 \ 99 那么这个时候:minParent = 66,min = 70,即 min 是父亲节点的右子节点 """ # 将 min 的右子树挂到父亲节点的右子树中 min_parent.right = right else: # 要删除 min 节点是父亲节点的左子节点 """ 比如我们要删除以下树的节点68 33 / \ 22 66 / \ 35 70 / \ 68 99 \ 69 那么这个时候:minParent = 70,min = 68,即 min 是父亲节点的左子节点 """ # 将 min 的右子树挂到父亲节点的左子树中 min_parent.left = right # 删掉 min 的右子树,这样可以使得 min 节点从树中断开 min_node.right = None self.size -= 1 if __name__ == '__main__': # bst = BST(lambda a, b: a - b) bst = BST(lambda a, b: a - b) bst.add(33) bst.add(22) bst.add(66) bst.add(12) bst.add(35) bst.add(70) bst.add(34) bst.add(50) bst.add(68) bst.add(99) print(bst.inOrder()) print(bst.contains(34)) print(bst.minValue()) print(bst.maxValue()) print(bst.removeMin()) print(bst.inOrder()) print(bst.removeMax()) print(bst.inOrder()) bst.remove_1(66) bst.remove_2(67) print(bst.inOrder())
class TreeNode: def __init__(self, data, left=None, right=None): self.data = data self.left = left self.right = right class BSTR: def __init__(self,__comp): self.root=None self.size=0 self.__comp=__comp def getsize(self): return self.size def isEmpty(self): return self.size==0 #插入:o(logn) def add(self,e): self.root=self.addR(self.root,e) #将e插入到以node为根节点的子树中 #返回插入节点后二叉查找树的根节点 def addR(self,node,e): #终止条件 if not node: self.size+=1 return TreeNode(e) # if self.__comp(e,node.data)<0: node.left=self.addR(node.left,e) elif self.__comp(e,node.data)>0: node.right=self.addR(node.right,e) # e的父亲节点 return node #修改:o(logn):set(src,target)会破坏二叉搜索树的顺序 #查询 def contains(self,target): node=self.find(target) if not node: return False return True #o(logn) def find(self,target): return self.findR(self.root,target) def findR(self,node,target): # if not node: return # if self.__comp(target,node.data)==0: return node elif self.__comp(target,node.data)<0: return self.findR(node.left,target) elif self.__comp(target,node.data)>0: return self.findR(node.right,target) def inOrder(self): res=[] def inOrderR(node): if not node: return [] inOrderR(node.left) res.append(node.data) inOrderR(node.right) inOrderR(self.root) return res #o(logn) def minValue(self): if not self.root: raise Exception('tree is null') return self.minValueR(self.root).data def minValueR(self,node): # if not node.left: return node # return self.minValueR(node.left) #o(logn) def maxValue(self): if not self.root: raise Exception('tree is null') return self.maxValueR(self.root).data def maxValueR(self, node): # if not node.right: return node # return self.maxValueR(node.right) #删除 #O(logn) def removeMin(self): if not self.root: raise Exception('tree is null') res=self.minValue() self.root=self.removeMinR(self.root) return res #删除以node为根节点的子树的最小节点 #返回删除完最小节点的子树的根节点 def removeMinR(self,node): # if not node.left: right_node=node.right node.right=None self.size-=1 return right_node # node.left=self.removeMinR(node.left) return node def removeMax(self): if not self.root: raise Exception('tree is null') res=self.maxValue() self.root=self.removeMaxR(self.root) return res #删除以node为根节点的子树的最大节点 #返回删除完最大节点的子树的根节点 def removeMaxR(self,node): # if not node.right: left_node=node.left node.left=None self.size-=1 return left_node # node.right=self.removeMaxR(node.right) return node def remove(self,e): self.root=self.removeR(self.root,e) def removeR(self,node,e): if not node: return None #找 if self.__comp(e,node.data)<0: node.left=self.removeR(node.left,e) return node elif self.__comp(e,node.data)>0: node.right=self.removeR(node.right,e) return node #删 else: #情况1 if not node.left: right_node = node.right node.right = None self.size -= 1 return right_node #情况2 if not node.right: left_node = node.left node.left = None self.size -= 1 return left_node #情况3(node的left和right都不为空):用‘后继节点’替代 successor=self.minValueR(node.right) #key:right->left successor.right=self.removeMinR(node.right) successor.left=node.left node.left=None node.right=None return successor if __name__ == '__main__': # bst = BST(lambda a, b: a - b) bst = BSTR(lambda a, b: a - b) bst.add(33) bst.add(22) bst.add(66) bst.add(12) bst.add(35) bst.add(70) bst.add(34) bst.add(50) bst.add(68) bst.add(99) print(bst.inOrder()) print(bst.contains(34)) print(bst.minValue()) print(bst.maxValue()) print(bst.removeMin()) print(bst.inOrder()) print(bst.removeMax()) print(bst.inOrder()) bst.remove(66) print(bst.inOrder()) bst.remove(68) print(bst.inOrder())
class TreeNode: def __init__(self,data,left=None,right=None,height=1): self.data=data self.left=left self.right=right self.height=height class AVLTree: def __init__(self,__comp): self.root=None self.size=0 self.__comp=__comp def getSize(self): return self.size def isEmpty(self): return self.size==0 def getHeight(self,node): if not node: return 0 return node.height #平衡因子:左右子节点高度差 def getBalanceFactor(self,node): if not node: return 0 return self.getHeight(node.left)-self.getHeight(node.right) #二叉树判断:增序排列 def isBST(self): res=self.inOrder() # if len(res)<=1: return True # for i in range(1,len(res)): if self.__comp(res[i],res[i-1])<0: return False return True #平衡树判断: def isBalanced(self): return self.isBalancedR(self.root) def isBalancedR(self,node): #终止条件 if not node: return True #递归下去 balance_factor=self.getBalanceFactor(node) if abs(balance_factor)>1: return False return self.isBalancedR(node.left) and self.isBalancedR(node.right) #转变平衡的操作:右旋与左旋 """ 对节点 y 进行向右旋转操作,返回旋转后新的根节点 x y x / \ / \ x T4 向右旋转 (y) z y / \ ---------------> / \ / \ z T3 T1 T2 T3 T4 / \ T1 T2 """ def rightRotate(self,y): #中介点 x=y.left t3=x.right #旋 x.right=y y.left=t3 #更新节点高度:先y后x-因为y为子节点 y.height=max(self.getHeight(y.left),self.getHeight(y.right))+1 x.height=max(self.getHeight(x.left),self.getHeight(x.right))+1 #返回调整后的根节点 return x """ 对节点y进行向左旋转操作,返回旋转后新的根节点x y x / \ / \ T4 x 向左旋转 (y) y z / \ - - - - - - - -> / \ / \ T3 z T4 T3 T1 T2 / \ T1 T2 """ def leftRotate(self,y): #中介点 x=y.right t3=x.left #旋 x.left=y y.right=t3 #更新节点高度:先y后x-因为y为子节点 y.height=max(self.getHeight(y.left),self.getHeight(y.right))+1 x.height=max(self.getHeight(x.left),self.getHeight(x.right))+1 #返回调整后的根节点 return x #插入:o(logn) def add(self,e): self.root=self.addR(self.root,e) #将节点e插入到以node为根节点的子树中 #返回此根节点 def addR(self,node,e): #终止条件 if not node: self.size-=1 return TreeNode(e) ####################递归############################### if self.__comp(e,node.data)<0: node.left=self.addR(node.left,e) if self.__comp(e,node.data)>0: node.right=self.addR(node.right,e) #更新高度 node.height=max(self.getHeight(node.left),self.getHeight(node.right))+1 #利用平衡因子判断是否平衡,并根据具体情况(四种),利用旋转规整 balance_factor=self.getBalanceFactor(node) #情况1:LL-左子节点增左子节点e if balance_factor>1 and self.getBalanceFactor(node.left)>=0: return self.rightRotate(node) #情况2:RR-右子节点增右子节点e if balance_factor<-1 and self.getBalanceFactor(node.right)<=0: return self.leftRotate(node) #情况3:LR-左子节点增右子节点e if balance_factor>1 and self.getBalanceFactor(node.left)<0: #先转LL node.left=self.leftRotate(node.left) return self.rightRotate(node) #情况4:RL-右子节点增左子节点e if balance_factor<-1 and self.getBalanceFactor(node.right)>0: #先转RR node.right=self.rightRotate(node.right) return self.leftRotate(node) return node #删除:o(logn) def minValueR(self, node): if not node.left: return node return self.minValueR(node.left) # 删除以 node 为根节点的子树的最小节点 # 并返回删除完最小节点的子树的根节点 def removeMinR(self, node): if not node.left: right_node = node.right node.right = None self.size -= 1 return right_node left_node = self.removeMinR(node.left) node.left = left_node return node def remove(self,e): self.root=self.removeR(self.root,e) def removeR(self,node,e): #终 if not node: return None #####################递归############################### #找 if self.__comp(e,node.data)<0: node.left=self.removeR(node.left,e) #方便后续更新节点高度与整平衡 retNode=node elif self.__comp(e,node.data)>0: node.right=self.removeR(node.right,e) retNode=node #删 else: if not node.left: right_node=node.right node.right=None self.size-=1 retNode=right_node elif not node.right: left_node=node.left node.left=None self.size-=1 retNode=left_node else: #node的左右子节点都不为空 #利用后继节点 successor=self.minValueR(node.right) successor.right=self.removeMinR(node.right) successor.left=node.left node.left=None node.right=None retNode=successor # if not retNode: return None # 更新高度 retNode.height = max(self.getHeight(retNode.left), self.getHeight(retNode.right)) + 1 # 利用平衡因子判断是否平衡,并根据具体情况(四种),利用旋转规整 balance_factor = self.getBalanceFactor(retNode) # 情况1:LL-左子节点增左子节点e if balance_factor > 1 and self.getBalanceFactor(retNode.left) >= 0: return self.rightRotate(retNode) # 情况2:RR-右子节点增右子节点e if balance_factor < -1 and self.getBalanceFactor(retNode.right) <= 0: return self.leftRotate(retNode) # 情况3:LR-左子节点增右子节点e if balance_factor > 1 and self.getBalanceFactor(retNode.left) < 0: # 先转LL retNode.left = self.leftRotate(retNode.left) return self.rightRotate(retNode) # 情况4:RL-右子节点增左子节点e if balance_factor < -1 and self.getBalanceFactor(retNode.right) > 0: # 先转RR retNode.right = self.rightRotate(retNode.right) return self.leftRotate(retNode) return retNode # 中序遍历 def inOrder(self): res = [] def inOrderR(node): if not node: return [] inOrderR(node.left) res.append(node.data) inOrderR(node.right) inOrderR(self.root) return res if __name__ == '__main__': avl = AVLTree(lambda x, y: x - y) avl.add(9) avl.add(10) avl.add(11) avl.add(13) print(avl.isBST()) print(avl.isBalanced())
BLACK=False RED=True class TreeNode: def __init__(self,data,left=None,right=None,color=RED): self.data=data self.left=left self.right=right #颜色 self.color=color class RBST: def __init__(self,__comp): self.root=None self.size=0 self.__comp=__comp def getSize(self): return self.size def isEmpty(self): return self.size==0 #判断节点颜色 def isRED(self,node): #空节点为黑 if not node: return BLACK return node.color """ node x / \ 左旋转 / \ T1 x -------> node T3 / \ / \ T2 T3 T1 T2 """ def leftRotate(self,node): #中介点 x=node.right t2=x.left #左旋 node.right=t2 x.left=node #转色 x.color=node.color node.color=RED return x """ node x / \ 右旋转 / \ x T2 -------> y node / \ / \ y T1 T1 T2 """ def rightRotate(self,node): #中介点 x=node.left t1=x.right #右旋 node.left=t1 x.right=node x.color=node.color node.color=RED return x #颜色翻转 def flipColors(self,node): node.color=RED node.left.color=BLACK node.right.color=BLACK #插入:o(logn) def add(self,e): self.root=self.addR(self.root,e) #保持根节点为黑 self.root.color=BLACK def addR(self,node,e): #终止条件 if not node: self.size+=1 return TreeNode(e) #递归 if self.__comp(e,node.data)<0: node.left=self.addR(node.left,e) elif self.__comp(e,node.data)>0: node.right=self.addR(node.right,e) else: return node #维护以node为根节点的子树黑平衡 if self.isRED(node.right) and not self.isRED(node.left): node=self.leftRotate(node) if self.isRED(node.left) and not self.isRED(node.left.left): node=self.rightRotate(node) if self.isRED(node.left) and self.isRED(node.right): node=self.flipColors(node) return node # 中序遍历 def inOrder(self): res = [] def inOrderR(node): if not node: return [] inOrderR(node.left) res.append(node.data) inOrderR(node.right) inOrderR(self.root) return res if __name__ == '__main__': avl = RBST(lambda x, y: x - y) avl.add(9) avl.add(10) avl.add(11) avl.add(13) print(avl.inOrder())
#方法一: class Node: def __init__(self,val,next=None): self.val=val self.next=next class DataStream: def __init__(self): self.dummy_node=Node(-1) #o(1) def add(self,val): new_node=Node(val) new_node.next=self.dummy_node.next self.dummy_node.next=new_node def removeMax(self): if not self.dummy_node.next: raise Exception('removeMax失败,因为数据流中无元素') #遍历链表,找最大值所在节点 curr=self.dummy_node.next max_value_node=curr while curr: if curr.val>max_value_node.val: max_value_node=curr curr=curr.next #找最大值节点的前一个节点 curr,max_value_node_prev=self.dummy_node.next,self.dummy_node while curr: if curr==max_value_node: break max_value_node_prev=curr curr=curr.next #删除 max_value_node_prev.next=max_value_node.next max_value_node.next=None return max_value_node.val if __name__=='__main__': ds=DataStream() ds.add(3) print(ds.removeMax())#3 ds.add(6) ds.add(5) print(ds.removeMax())#6 ds.add(2) ds.add(1) print(ds.removeMax())#5
#方法二: class Node: def __init__(self,val,next=None): self.val=val self.next=next class DataStream: def __init__(self): self.dummy_node=Node(-1) #o(1):按头节点值最大存储规则 def add(self, val): #找:第一个比val小的节点 prev,curr=self.dummy_node,self.dummy_node.next while curr: if curr.val<val: break prev=curr curr=curr.next #将元素添加至该节点前面 new_node=Node(val,curr) prev.next=new_node #o(1) def removeMax(self): if not self.dummy_node.next: raise Exception('removeMax失败,因为数据流中无元素') #保存需要返回的最大值(头节点值) res=self.dummy_node.next.val #删除(头节点) head=self.dummy_node.next self.dummy_node.next=head.next head.next=None return res if __name__=='__main__': ds=DataStream() ds.add(3) print(ds.removeMax())#3 ds.add(6) ds.add(5) print(ds.removeMax())#6 ds.add(2) ds.add(1) print(ds.removeMax())#5
class MaxHeap: def __init__(self,__comp,data=None): self.__comp=__comp if not data: self.data=[] else: self.data=data[:] for i in range(self.lastNonLeafIndex(),-1,-1): self.siftDown(i) def size(self): return len(self.data) def isEmpty(self): return len(self.data)==0 #左孩子节点索引 def leftChild(self,index): return index*2+1 #右孩子节点索引 def rightChild(self,index): return index*2+2 #父节点索引 def parent(self,index): if index==0: raise Exception('index-0 does not have parent') return (index-1)//2 #最后一个父节点:最后一个叶子结点的父节点 def lastNonLeafIndex(self): #最后一个叶子节点索引 last_leaf_index=len(self.data)-1 #转化 return self.parent(last_leaf_index) #上浮保持完全二叉树 def siftUp(self,index): e=self.data[index] while index>0: parent_node_val=self.data[self.parent(index)] #循环比较:小值通过赋值下浮 if self.__comp(e,parent_node_val)<=0: break self.data[index]=parent_node_val index=self.parent(index) #最后’index’处进行赋值 self.data[index]=e #下浮保持完全二叉树 def siftDown(self,index): e=self.data[index] while self.leftChild(index)<len(self.data): #寻左右子节点中最大值节点 max_node_index=self.leftChild(index) if self.rightChild(index)<len(self.data): right_node_val=self.data[self.rightChild(index)] left_node_val=self.data[self.leftChild(index)] if self.__comp(right_node_val,left_node_val)>0: max_node_index=self.rightChild(index) # 循环比较:大值通过赋值上浮 if self.__comp(e,self.data[max_node_index])>=0: break self.data[index]=self.data[max_node_index] index=max_node_index # 最后’index’处进行赋值 self.data[index]=e #o(logn) def add(self,e): self.data.append(e) self.siftUp(len(self.data)-1) def findMax(self): if self.isEmpty(): raise Exception('Heap is Empty') return self.data[0] #o(logn) def removeMax(self): max_val=self.findMax() #最后节点替换为头节点,并删除 last=self.data[len(self.data)-1] self.data[0]=last self.data.pop() #通过下沉恢复成大顶堆 if len(self.data)>=1: self.siftDown(0) return max_val class DataStream: def __init__(self, __comp): self.maxHeap = MaxHeap(__comp) # 时间复杂度:O(logn) def add(self, val): self.maxHeap.add(val) # O(logn) def removeMax(self): return self.maxHeap.removeMax() def sort(data): # 1. 建堆,堆化 O(n) max_heap = MaxHeap(lambda a, b: a - b, data) # 2. 排序 i, tmp = len(data) - 1, [0] * len(data) # O(nlogn) while not max_heap.isEmpty(): tmp[i] = max_heap.removeMax() i -= 1 # 3. 拷贝 for i in range(len(data)): data[i] = tmp[i] if __name__ == '__main__': ds = DataStream(lambda a, b: a - b) ds.add(3) print(ds.removeMax()) # 打印 3 ds.add(6) ds.add(5) print(ds.removeMax()) # 打印 6 ds.add(2) ds.add(1) print(ds.removeMax()) # 打印 5 #HeapSort data = [15, 17, 19, 13, 22, 16, 28, 30, 42, 66] sort(data) print(data)
class MaxHeap: def __init__(self,__comp,data=None): self.__comp=__comp if not data: self.data=[] else: self.data=data[:] for i in range(self.lastNonLeafIndex(),-1,-1): self.siftDown(i) def size(self): return len(self.data) def isEmpty(self): return len(self.data)==0 #左孩子节点索引 def leftChild(self,index): return index*2+1 #右孩子节点索引 def rightChild(self,index): return index*2+2 #父节点索引 def parent(self,index): if index==0: raise Exception('index-0 does not have parent') return (index-1)//2 #最后一个父节点:最后一个叶子结点的父节点 def lastNonLeafIndex(self): #最后一个叶子节点索引 last_leaf_index=len(self.data)-1 #转化 return self.parent(last_leaf_index) #上浮保持完全二叉树 def siftUp(self,index): e=self.data[index] while index>0: parent_node_val=self.data[self.parent(index)] #循环比较:小值通过赋值下浮 if self.__comp(e,parent_node_val)<=0: break self.data[index]=parent_node_val index=self.parent(index) #最后’index’处进行赋值 self.data[index]=e #下浮保持完全二叉树 def siftDown(self,index): e=self.data[index] while self.leftChild(index)<len(self.data): #寻左右子节点中最大值节点 max_node_index=self.leftChild(index) if self.rightChild(index)<len(self.data): right_node_val=self.data[self.rightChild(index)] left_node_val=self.data[self.leftChild(index)] if self.__comp(right_node_val,left_node_val)>0: max_node_index=self.rightChild(index) # 循环比较:大值通过赋值上浮 if self.__comp(e,self.data[max_node_index])>=0: break self.data[index]=self.data[max_node_index] index=max_node_index # 最后’index’处进行赋值 self.data[index]=e #o(logn) def add(self,e): self.data.append(e) self.siftUp(len(self.data)-1) def findMax(self): if self.isEmpty(): raise Exception('Heap is Empty') return self.data[0] #o(logn) def removeMax(self): max_val=self.findMax() #最后节点替换为头节点,并删除 last=self.data[len(self.data)-1] self.data[0]=last self.data.pop() #通过下沉恢复成大顶堆 if len(self.data)>=1: self.siftDown(0) return max_val class PriorityQueue: def __init__(self,__comp): self.maxHeap=MaxHeap(__comp) def getsize(self): return self.maxHeap.size() def isEmpty(self): return self.maxHeap.isEmpty() def enqueue(self,e): self.maxHeap.add(e) def dequeue(self): return self.maxHeap.removeMax() def getFront(self): return self.maxHeap.findMax() if __name__ == '__main__': ds = PriorityQueue(lambda a, b: a - b) ds.enqueue(3) print(ds.dequeue()) # 打印 3 ds.enqueue(6) ds.enqueue(5) print(ds.dequeue()) # 打印 6 ds.enqueue(2) ds.enqueue(1) print(ds.dequeue()) # 打印 5
class ArraySet: def __init__(self): self.data=[] def size(self): return len(self.data) def isEmpty(self): return len(self.data)==0 #o(1) def add(self,e): if self.data.count(e)==0: self.data.append(e) def remove(self,e): if self.data.count(e)>0: self.data.remove(e) def contain(self,e): return self.data.count(e)>0 def toString(self): return "ArraySet[ data = {} ]".format(self.data) if __name__=='__main__': set1=ArraySet() set1.add(2) set1.add(4) set1.add(1) print(set1.toString()) set1.add(2) print(set1.toString()) print(set1.contain(4)) set1.remove(1) print(set1.toString())
class Node: def __init__(self, e, next=None): self.e = e self.next = next def toString(self): return str(self.e) class LinkedList: def __init__(self): self.dummyHead = Node(-1) self.size = 0 def getSize(self): return self.size def isEmpty(self): return self.size == 0 """ 查询操作 """ # 查询指定索引的节点的值 # 时间复杂度: O(n) def get(self, index): if index < 0 or index >= self.getSize(): raise Exception("get failed, require index >= 0 && index < size") curr = self.dummyHead.next for i in range(0, index): curr = curr.next return curr.e # 时间复杂度: O(1) def getFirst(self): return self.get(0) def getLast(self): return self.get(self.size - 1) """ 修改操作 """ # 修改指定索引的节点元素 # 时间复杂度: O(n) def set(self, index, e): if index < 0 or index >= self.getSize(): raise Exception("set failed, require index >= 0 && index < size") curr = self.dummyHead.next for i in range(0, index): curr = curr.next curr.e = e """ 新增操作 """ # 在指定索引的位置插入新的节点 # 时间复杂度: O(n) def add(self, index, e): if index < 0 or index > self.getSize(): raise Exception("add failed, require index >= 0 && index < size") prev = self.dummyHead for i in range(0, index): prev = prev.next prev.next = Node(e, prev.next) self.size += 1 # 在链表表头新增节点 # 时间复杂度: O(1) def addFirst(self, e): self.add(0, e) # 在链表表尾新增节点 # 时间复杂度: O(n) def addLast(self, e): self.add(self.size, e) """ 删除操作 """ # 删除指定索引的节点,并返回删除的节点的值 # 时间复杂度: O(n) def remove(self, index): if index < 0 or index >= self.getSize(): raise Exception("remove failed, require index >= 0 && index < size") prev = self.dummyHead for i in range(0, index): prev = prev.next del_node = prev.next prev.next = del_node.next del_node.next = None self.size -= 1 return del_node.e # 时间复杂度: O(1) def removeFirst(self): return self.remove(0) # 时间复杂度: O(n) def removeLast(self): return self.remove(self.size - 1) # 删除第一个值等于 e 的节点 # 时间复杂度: O(n) def removeElement(self, e): if self.dummyHead.next is None: raise Exception("removeElement failed, LinkedList is Empty") prev, curr = self.dummyHead, self.dummyHead.next while curr: if curr.e == e: break prev = curr curr = curr.next # bug 修复,需要先判断 curr # 如果 curr 为 None 的话,说明链表中不存在值等于 e 的节点 if curr: prev.next = curr.next curr.next = None # 判断链表中是否存在指定元素 # 时间复杂度: O(n) def contains(self, e): curr = self.dummyHead.next while curr: if curr.e == e: return True curr = curr.next return False def toString(self): res = "" curr = self.dummyHead.next while curr: res += curr.toString() + "=>" curr = curr.next res += "null" return res class LinkedListSet: def __init__(self): self.data=LinkedList() def size(self): return self.data.getSize() def isEmpty(self): return self.data.isEmpty() def add(self,e): if not self.data.contains(e): self.data.addFirst(e) def remove(self,e): if self.data.contains(e): self.data.removeElement(e) def contains(self,e): return self.data.contains(e) def toString(self): return 'LinkedListSet[ data={} ]'.format(self.data.toString()) if __name__ == '__main__': set1 = LinkedListSet() set1.add(2) set1.add(4) set1.add(1) print(set1.toString()) set1.add(2) print(set1.toString()) print(set1.contains(4)) set1.remove(1) print(set1.toString())
class TreeNode: def __init__(self, data, left=None, right=None): self.data = data self.left = left self.right = right class BST: def __init__(self, __comp): self.root = None self.size = 0 self.__comp = __comp def getSize(self): return self.size def isEmpty(self): return self.size == 0 # 插入:o(logn) def add(self, e): if self.root is None: self.root = TreeNode(e) else: curr = self.root while curr: # 比较 if self.__comp(e, curr.data) == 0: return elif self.__comp(e, curr.data) < 0 and not curr.left: curr.left = TreeNode(e) self.size += 1 return elif self.__comp(e, curr.data) > 0 and not curr.right: curr.right = TreeNode(e) self.size += 1 return if self.__comp(e, curr.data) < 0: curr = curr.left else: curr = curr.right # 修改o(logn):set(src,target)会破坏二叉搜索树的顺序 #查询 def contains(self, target): node = self.find(target) if not node: return False return True #O(logn) def find(self, target): if not self.root: return None curr = self.root while curr: if self.__comp(target, curr.data) == 0: return curr elif self.__comp(target, curr.data) < 0: curr = curr.left else: curr = curr.right return None # 中序遍历:方便观察结果,找bug def inOrder(self): res = [] def inOrderR(node): if not node: return [] inOrderR(node.left) res.append(node.data) inOrderR(node.right) inOrderR(self.root) return res #O(logn) def minValue(self): if not self.root: raise Exception("tree is null") min_node = self.root while min_node.left: #最深最左 min_node = min_node.left return min_node.data #O(logn) def maxValue(self): if not self.root: raise Exception("tree is null") max_node = self.root while max_node.right: #最深最右 max_node = max_node.right return max_node.data #删除 #O(logn) def removeMin(self): if not self.root: raise Exception("tree is null") # 找 min_node, parent = self.root, None while min_node.left: parent = min_node min_node = min_node.left #删 if not parent: #位于根节点处 self.root = self.root.right else: #key parent.left = min_node.right min_node.right = None self.size -= 1 return min_node.data # 时间复杂度:O(logn) def removeMax(self): if not self.root: raise Exception("tree is null") # 找 max_node, parent = self.root, None while max_node.right: parent = max_node max_node = max_node.right #删 if not parent: #位于根节点处 self.root = self.root.left else: parent.right = max_node.left max_node.left = None self.size -= 1 return max_node.data #优化: O(logn) def remove_2(self, e): if not self.root: return #找 curr, parent = self.root, None while curr and self.__comp(e, curr.data) != 0: parent = curr if self.__comp(e, curr.data) < 0: curr = curr.left else: curr = curr.right # 如果没有找到需要删除的元素,则直接返回 if not curr: return #情况简化 if curr.left and curr.right: #找右子树最小值 min_node, min_parent = curr.right, curr while min_node.left: min_parent = min_node min_node = min_node.left #覆盖该删除节点值 curr.data = min_node.data #curr变为叶子节点:情况则简化成三种 curr, parent = min_node, min_parent #确定开删节点是仅有一个子树节点还是叶子节点 if curr.left: child = curr.left # if parent: # curr.left = None elif curr.right: child = curr.right # if parent: # curr.right = None else: child = None #开删 if not parent: self.root = child elif curr == parent.left: parent.left = child elif curr == parent.right: parent.right = child self.size -= 1 #o(logn) def remove_1(self, e): if not self.root: return curr, parent = self.root, None # 找 while curr and self.__comp(e, curr.data) != 0: parent = curr if self.__comp(e, curr.data) < 0: curr = curr.left else: curr = curr.right # 如果没有找到需要删除的元素,则直接返回 if not curr: return # 删 if not curr.left and not curr.right: if not parent: self.root = None elif curr == parent.left: parent.left = None elif curr == parent.right: parent.right = None elif curr.left and not curr.right: if not parent: self.root = curr.left elif curr == parent.left: parent.left = curr.left curr.left = None elif curr == parent.right: parent.right = curr.left curr.left = None elif not curr.left and curr.right: if not parent: self.root = curr.right elif curr == parent.left: parent.left = curr.right curr.right = None elif curr == parent.right: parent.right = curr.right curr.right = None elif curr.left and curr.right: #找右子树最小值 min_node, min_parent = curr.right, curr while min_node.left: min_parent = min_node min_node = min_node.left ##覆盖该删除节点值 curr.data = min_node.data #覆盖该删除节点值 # 先拿到要删除 min 节点的右子树 right = min_node.right # bug 修复:这里删除 min 节点,需要区分 min 是父亲节点的右子节点还是左子节点 # 要删除 min 节点是父亲节点的右子节点 if min_parent.right == min_node: """ 比如我们要删除以下树的节点70 33 / \ 22 66 / \ 35 70 \ 99 那么这个时候:minParent = 66,min = 70,即 min 是父亲节点的右子节点 """ # 将 min 的右子树挂到父亲节点的右子树中 min_parent.right = right else: # 要删除 min 节点是父亲节点的左子节点 """ 比如我们要删除以下树的节点68 33 / \ 22 66 / \ 35 70 / \ 68 99 \ 69 那么这个时候:minParent = 70,min = 68,即 min 是父亲节点的左子节点 """ # 将 min 的右子树挂到父亲节点的左子树中 min_parent.left = right # 删掉 min 的右子树,这样可以使得 min 节点从树中断开 min_node.right = None self.size -= 1 class BSTSet: def __init__(self, __comp): self.bst = BST(__comp) def size(self): return self.bst.getSize() def isEmpty(self): return self.bst.isEmpty() def add(self, e): self.bst.add(e) def remove(self, e): self.bst.remove_1(e) def contains(self, e): return self.bst.contains(e) def toString(self): return "BSTSet[ data = {} ]".format(self.bst.inOrder()) if __name__ == '__main__': set1 = BSTSet(lambda a, b: a - b) set1.add(2) set1.add(4) set1.add(1) print(set1.toString()) set1.add(2) print(set1.toString()) print(set1.contains(4)) set1.remove(1) print(set1.toString())
#基本实现
class HashSet: def __init__(self,__hash): self.data=[None]*10 self.__size=0 self.__hash=__hash #e对应hash值 def hash(self,e,length): return abs(self.__hash(e))%length def size(self): return self.__size def isEmpty(self): return self.__size==0 def add(self,e): index=self.hash(e,len(self.data)) if not self.data[index]: self.data[index]=e self.__size+=1 #扩容 if self.__size==len(self.data): self.resize(2*len(self.data)) def resize(self,newCapacity): new_data=[None]*newCapacity for i in range(len(self.data)): if self.data[i]: new_index=self.hash(self.data[i],newCapacity) new_data[new_index]=self.data[i] self.data=new_data def remove(self,e): index=self.hash(e,len(self.data)) if self.data[index]: self.data[index]=None self.__size-=1 def contains(self,e): index=self.hash(e,len(self.data)) return self.data[index]!=None def toString(self): return 'HashSet [data = {} ]'.format(self.data) if __name__ == '__main__': set1 = HashSet(lambda a: a) set1.add(2) set1.add(4) set1.add(1) print(set1.toString()) set1.add(2) print(set1.toString()) print(set1.contains(4)) set1.remove(1) print(set1.toString())
#解决Hash冲突:基于开放寻址
class Item: def __init__(self,data): self.data=data self.is_deleted=False def toString(self): return str(self.data) class HashSet: def __init__(self,__hash,__equal): self.items=[None]*10 self.__size=0 self.__hash=__hash self.__equal=__equal #记录删除元素个数 self.delete_count=0 #扩展因子 self.loadFactor=0.75 def hash(self,e,length): return abs(self.__hash(e))%length def size(self): return self.__size def isEmpty(self): return self.__size==0 def add(self,e): index=self.hash(e,len(self.items)) #若已存在且为e,直接返回 if self.items[index] and self.__equal(e, self.items[index]): return # 辅助变量 add_index,is_first=index,True #找:等于null或已删除的第一个元素 while self.items[index] and not self.items[index].is_deleted: if (not self.items[index] or self.items[index].is_deleted) and is_first: add_index,is_first=index,False index+=1 index=index%len(self.items) #找到:add_index为null或已删除元素 #若为已删除元素,通过add后,count-=1 if self.items[add_index] and self.items[add_index].is_deleted: self.delete_count-=1 # self.items[add_index] = Item(e) self.__size += 1 #扩容 if self.__size>=len(self.items)*self.loadFactor: self.resize(2*len(self.items)) def resize(self,newCapacity): new_data=[None]*newCapacity for i in range(len(self.items)): if self.items[i] and not self.items[i].is_deleted: new_index=self.hash(self.items[i],newCapacity) new_data[new_index]=self.items[i] self.items=new_data #清理标记删除元素 self.delete_count=0 def remove(self,e): index=self.hash(e,len(self.items)) #找:等于e或null的元素 while self.items[index] and not self.__equal(e,self.items[index].data): index+=1 index=index%len(self.items) if self.items[index]: self.items[index].is_deleted=True self.__size-=1 self.delete_count+=1 #删除标记太多,缩容 if self.delete_count+self.__size>=len(self.items)*self.loadFactor: self.resize(len(self.items)) def contains(self,e): index=self.hash(e,len(self.items)) #找 while self.items[index] and not self.__equal(e,self.items[index].data): index+=1 index=index%len(self.items) #找到 return self.items[index] and not self.items[index].is_deleted def toString(self): res='' for data in self.items: if data and not data.is_deleted: res+=data.toString()+',' return res if __name__=='__main__': set1 = HashSet(lambda a: a, lambda a, b: a == b) set1.add(2) set1.add(4) set1.add(1) print(set1.toString()) set1.add(2) print(set1.toString()) print(set1.contains(4)) set1.remove(1) print(set1.toString()) #找到
#解决Hash冲突:基于链表:
class Node: def __init__(self,val,next=None): self.val=val self.next=next def toString(self): return str(self.val) class HashSet: def __init__(self,__hash,__equal): self.data=[None]*10 self.__size=0 self.__hash=__hash self.__equal=__equal self.loadFactor=0.75 def hash(self,e,length): return abs(self.__hash(e))%length def size(self): return self.__size def isEmpty(self): return self.__size==0 def add(self,e): index=self.hash(e,len(self.data)) # if not self.data[index]: self.data[index]=Node(e) self.__size+=1 # prev,curr=None,self.data[index] while curr: if self.__equal(e,curr.val): return prev=curr curr=curr.next prev.next=Node(e) self.__size+=1 #扩容 if self.__size==len(self.data)*self.loadFactor: self.resize(2*len(self.data)) def resize(self,newCapacity): new_data=[None]*newCapacity for i in range(len(self.data)): curr=self.data[i] while curr: e=curr.val new_index = self.hash(e, newCapacity) # 通过数组属性,定位 head = new_data[new_index] # 通过链表属性,扩链 if not head: new_data[new_index] = Node(e) else: new_data[new_index] = Node(e) new_data[new_index].next = head curr = curr.next self.data=new_data def remove(self,e): index=self.hash(e,len(self.data)) # if not self.data[index]: return # prev,curr=None,self.data[index] while curr: if self.__equal(e,curr.val): if not prev: #e为头节点 self.data[index]=curr.next else: prev.next=curr.next curr.next=None self.__size-=1 break prev=curr curr=curr.next def contains(self,e): index=self.hash(e,len(self.data)) if not self.data[index]: return False curr=self.data[index] while curr: if self.__equal(e,curr.val): return True curr=curr.next return False def toString(self): res='' for node in self.data: while node: res+=node.toString()+'=>' node=node.next return res if __name__ == '__main__': set1 = HashSet(lambda a: a, lambda a, b: a == b) set1.add(2) set1.add(4) set1.add(1) print(set1.toString()) set1.add(2) print(set1.toString()) print(set1.contains(4)) set1.remove(1) print(set1.toString())
#链表Map
class Node: def __init__(self,key=None,value=None,next=None): self.key=key self.value=value self.next=next def toString(self): return str(self.key)+'->'+str(self.value) class LinkedListMap: def __init__(self,__equal): self.dummyHead=Node() self.__size=0 self.__equal=__equal def size(self): return self.__size def isEmpty(self): return self.__size==0 def add(self,key,value): curr=self.getNode(key) # if not curr: self.dummyHead.next=Node(key,value,self.dummyHead.next) self.__size+=1 else: curr.value=value def getNode(self,key): curr=self.dummyHead.next while curr: if self.__equal(key,curr.key): break curr=curr.next return curr def remove(self,key): #定位 prev,curr=self.dummyHead,self.dummyHead.next while curr: if self.__equal(key,curr.key): break prev=curr curr=curr.next #删 if curr: prev.next=curr.next curr.next=None self.__size-=1 return curr.value return None def set(self,key,new_value): curr=self.getNode(key) if curr: curr.value=new_value else: raise Exception('没有对应的key:{}'.format(key)) def get(self,key): node=self.getNode(key) return node.value if node else None def containsKey(self,key): node=self.getNode(key) return node!=None
#二叉搜索树Map
class TreeNode: def __init__(self,key,value,left=None,right=None): self.key=key self.value=value self.left=left self.right=right class BSTMap: def __init__(self,__comp): self.root=None self.__size=0 self.__comp=__comp def size(self): return self.__size def isEmpty(self): return self.__size==0 #o(logn) def add(self,key,value): self.root=self.addR(self.root,key,value) def addR(self,node,key,value): #终止条件 if not node: self.__size+=1 return TreeNode(key,value) #递归 if self.__comp(key,node.key)<0: node.left=self.addR(node.left,key,value) elif self.__comp(key,node.key)>0: node.right=self.addR(node.right,key,value) return node #o(logn) def remove(self,key): node=self.getR(self.root,key) # if not node: return None # if self.__comp(key,node.key)<0: node.left=self.removeR(node.left,key) return node elif self.__comp(key,node.key)>0: node.right=self.removeR(node.right,key) else: #找到:删除节点为node #情况一 if not node.left: # right_node=node.right # node.right=None self.__size-=1 return right_node #情况2 if not node.right: # left_node=node.left # node.left=None self.__size-=1 return left_node #情况3 successor=self.minValueR(node.right) #注意次序 successor.right=self.removeMinR(node.right) successor.left=node.left node.left=None node.right=None return successor def minValueR(self, node): if not node.left: return node return self.minValueR(node.left) # 删除以 node 为根节点的子树的最小节点 # 并返回删除完最小节点的子树的根节点 def removeMinR(self, node): if not node.left: right_node = node.right node.right = None self.size -= 1 return right_node left_root = self.removeMinR(node.left) node.left = left_root return node def set(self,key,new_value): node=self.getR(self.root,key) # if not node: raise Exception('没有对应的key:{}'.format(key)) # node.value=new_value def get(self,key): node=self.getR(self.root,key) return node.value if node else None def getR(self,node,key): if not node: return None if self.__comp(key,node.key)==0: return node elif self.__comp(key,node.key)<0: return self.getR(node.left,key) else: return self.getR(node.right,key) def contains(self,key): node=self.getR(self.root,key) return node!=None
#HashMap
class Node: def __init__(self,key=None,value=None,next=None): self.key=key self.value=value self.next=next def toString(self): return str(self.key)+'->'+str(self.value) class HashMap: def __init__(self,__hash,__equal,initCapacity=25,loadFactor=0.75): self.data=[None]*initCapacity self.__size=0 self.__hash=__hash self.__equal=__equal self.loadFactor=loadFactor #key->索引 def hash(self,key,length): return abs(self.__hash(key))%length def size(self): return self.__size def isEmpty(self): return self.__size def add(self,key,value): #目:'数组'属性位置 index=self.hash(key,len(self.data)) #目:链表属性位置 curr=self.getNode(key,index) if not curr: self.data[index]=Node(key,value,self.data[index]) self.__size+=1 #扩容 if self.__size>=len(self.data)*self.loadFactor: self.resize(2*len(self.data)) else: curr.value=value def getNode(self,key,index): curr=self.data[index] while curr: if self.__equal(key,curr.key): break curr=curr.next return curr def resize(self,new_capacity): new_data=[None]*new_capacity for i in range(len(self.data)): curr=self.data[i] while curr: #'数组'属性定位 key=curr.key new_index=self.hash(key,new_capacity) head=new_data[new_index] #链表属性扩容 if not head: new_data[new_index] = Node(key, curr.value) else: new_data[new_index] = Node(key, curr.value) new_data[new_index].next=head curr=curr.next self.data=new_data def remove(self,key): index=self.hash(key,len(self.data)) # if not self.data[index]: return None # prev,curr=None,self.data[index] while curr: if self.__equal(key,curr.key): #删头 if not prev: self.data[index]=curr.next else: prev.next=curr.next curr.next=None self.__size -= 1 return curr.value prev=curr curr=curr.next return None def set(self,key,new_value): index=self.hash(key,len(self.data)) node=self.getNode(key,index) if node: node.value=new_value else: raise Exception("没有对应的 key :{}".format(key)) def get(self,key): index = self.hash(key, len(self.data)) node = self.getNode(key, index) return node.value if node else None def containkey(self,key): index = self.hash(key, len(self.data)) node = self.getNode(key, index) return node!=None
import random MAX_LEVEL=16 class Node: def __init__(self,data): self.data=data #key:在每一层维护索引节点 self.nextNodes=[None]*MAX_LEVEL self.maxIndexLevel=0 class SkipList: def __init__(self,__comp): #记录当前跳表最大高度(包含原始链表层) self.levelCount=1 self.dummyHead=Node(-1) self.__comp=__comp def contains(self,e): return self.get(e) def get(self,e): curr=self.dummyHead for i in range(self.levelCount-1,-1,-1): while curr.nextNodes[i] and self.__comp(curr.nextNodes[i].data,e)<0: curr=curr.nextNodes[i].data if curr.nextNodes[0] and self.__comp(curr.nextNodes[0].data,e)==0: return curr.nextNodes[0] return None #目:一层add后,维护上层索引(<=MAX_LEVEL) def randomLevel(self): level=1 for i in range(1,MAX_LEVEL): if random.randint(0,MAX_LEVEL)%2==1: level+=1 return level def add(self,e): level=self.randomLevel() if self.dummyHead.nextNodes[0] else 1 #在各维护层中建立初始化虚拟头节点 prevNodes=[None]*level for i in range(level): prevNodes[i]=self.dummyHead #找 #定位于插入节点的前一个节点prev,并赋予prevNodes prev=self.dummyHead for i in range(self.levelCount-1,-1,-1): while prev.nextNodes[i] and self.__comp(prev.nextNodes[i].data,e)<0: prev=prev.nextNodes[i] if i<level: prevNodes[i]=prev #添 #维护各层 new_node=Node(e) #调整属性 new_node.maxIndexLevel=level for i in range(level): new_node.nextNodes[i]=prev.nextNodes[i] prev.nextNodes[i]=new_node #更新链表高度 if self.levelCount<level: self.levelCount=level def remove(self,e): prevNodes=[None]*self.levelCount #找 prev=self.dummyHead for i in range(self.levelCount-1,-1,-1): while prev.nextNodes[i] and self.__comp(prev.nextNodes[i].data,e)<0: prev=prev.nextNodes[i] prevNodes[i]=prev #删 if prev.nextNodes[0] and self.__comp(prev.nextNodes[0].data,e)==0: for i in range(self.levelCount-1,-1,-1): del_node=prevNodes[i].nextNodes[i] if del_node and self.__comp(del_node.data,e)==0: prevNodes[i].nextNodes[i]=del_node.nextNodes[i] del_node.nextNodes[i]=None
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。