mirror of
https://github.com/heqin-zhu/algorithm.git
synced 2024-03-22 13:30:46 +08:00
141 lines
4.1 KiB
Python
141 lines
4.1 KiB
Python
''' 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)
|