''' mbinary ######################################################################### # File : intervalTree.py # Author: mbinary # Mail: zhuheqin1@gmail.com # Blog: https://mbinary.xyz # Github: https://github.com/mbinary # Created Time: 2018-11-18 10:48 # Description: ######################################################################### ''' from redBlackTree import redBlackTree from functools import total_ordering @total_ordering class node: def __init__(self,low,high,left=None,right=None,isBlack=False): self.val = low # self.val is the low self.high = high self.max = high self.left = left self.right = right self.parent=None self.isBlack = isBlack def __lt__(self,nd): return self.val < nd.val def __eq__(self,nd): return nd is not None and self.val == nd.val def setChild(self,nd,isLeft = True): if isLeft: self.left = nd else: self.right = nd if nd is not None: nd.parent = self def getChild(self,isLeft): if isLeft: return self.left else: return self.right def __bool__(self): return self.val is not None def __str__(self): color = 'B' if self.isBlack else 'R' return f'{color}[{self.val},{self.high}]-{self.max}' def __repr__(self): return f'intervalNode({self.val},{self.high},{self.max},isBlack={self.isBlack})' def overlap(self,low,high): return self.val<=high and self.high>=low def setMax(self): l = 0 if self.left is None else self.left.max r = 0 if self.right is None else self.right.max self.max = max(self.high, l, r) return self.max class intervalTree(redBlackTree): def search(self,low,high): nd = self.root while nd is not None and not nd.overlap(low,high): if nd.left is not None and nd.left.max>=low: nd = nd.left else:nd = nd.right return nd def insert(self,nd): super(intervalTree,self).insert(nd) while nd is not None: nd.setMax() nd = nd.parent def delete(self,val): nd = self.find(val) if nd is not None: nd.max = 0 tmp = nd.parent while tmp is not None: tmp.setMax() tmp = tmp.parent super(intervalTree,self).delete(val) def rotate(self,prt,chd): '''rotate prt, and return new prt, namyly the original chd''' super(intervalTree,self).rotate(prt,chd) prt.setMax() chd.setMax() def copyNode(self,src,des): des.val = src.val des.high = src.high des.setMax() from random import randint, shuffle def genNum(n =10,upper=10): nums ={} for i in range(n): while 1: d = randint(0,100) if d not in nums: nums[d] = (d,randint(d,d+upper)) break return nums.values() def buildTree(n=10,nums=None,visitor=None): #if nums is None or nums ==[]: nums = genNum(n) tree = intervalTree() print(f'build a red-black tree using {nums}') for i in nums: tree.insert(node(*i)) if visitor: visitor(tree,i) return tree,nums def testInsert(nums=None): def visitor(t,val): print('inserting', val) print(t) tree,nums = buildTree(visitor = visitor,nums=nums) print('-'*5+ 'in-order visit' + '-'*5) for i,j in enumerate(tree.sort()): print(f'{i+1}: {j}') return tree def testSuc(nums=None): tree,nums = buildTree(nums=nums) for i in tree.sort(): print(f'{i}\'s suc is {tree.getSuccessor(i)}') def testDelete(nums=None): tree,nums = buildTree(nums = nums) print(tree) for i in nums: print(f'deleting {i}') tree.delete(i[0]) print(tree) return tree if __name__=='__main__': lst = [(0,3),(5,8),(6,10),(26,26),(25,30),(8,9),(19,20),(15,23),(16,21),(17,19)] #lst = None #testSuc(lst) tree = testInsert(lst) #tree,_= buildTree(lst) while 1: a =int( input('low:')) b =int( input('high:')) res = tree.search(a,b) print(res)