2018-07-08 23:28:29 +08:00
|
|
|
''' mbinary
|
|
|
|
#########################################################################
|
|
|
|
# File : leftHeap.py
|
|
|
|
# Author: mbinary
|
|
|
|
# Mail: zhuheqin1@gmail.com
|
2019-01-31 12:09:46 +08:00
|
|
|
# Blog: https://mbinary.xyz
|
2018-07-08 23:28:29 +08:00
|
|
|
# Github: https://github.com/mbinary
|
|
|
|
# Created Time: 2018-05-19 23:06
|
|
|
|
# Description:
|
|
|
|
#########################################################################
|
|
|
|
'''
|
|
|
|
|
|
|
|
from functools import total_ordering
|
|
|
|
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
@total_ordering
|
2018-07-08 23:28:29 +08:00
|
|
|
class node:
|
2020-04-15 12:28:20 +08:00
|
|
|
def __init__(self, val, freq=1, s=1, left=None, right=None):
|
|
|
|
self.val = val
|
|
|
|
self.freq = freq
|
|
|
|
self.s = s
|
2018-07-08 23:28:29 +08:00
|
|
|
if left is None or right is None:
|
|
|
|
self.left = left if left is not None else right
|
2020-04-15 12:28:20 +08:00
|
|
|
self.right = None
|
2018-07-08 23:28:29 +08:00
|
|
|
else:
|
2020-04-15 12:28:20 +08:00
|
|
|
if left.s < right.s:
|
|
|
|
left, right = right, left
|
|
|
|
self.left = left
|
|
|
|
self.right = right
|
|
|
|
self.s += self.right.s
|
|
|
|
|
|
|
|
def __eq__(self, nd):
|
|
|
|
return self.val == nd.val
|
|
|
|
|
|
|
|
def __lt__(self, nd):
|
|
|
|
return self.val < nd.val
|
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
def __repr__(self):
|
2020-04-15 12:28:20 +08:00
|
|
|
return 'node(val=%d,freq=%d,s=%d)' % (self.val, self.freq, self.s)
|
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
|
|
|
|
class leftHeap:
|
2020-04-15 12:28:20 +08:00
|
|
|
def __init__(self, root=None):
|
|
|
|
self.root = root
|
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
def __bool__(self):
|
|
|
|
return self.root is not None
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
@staticmethod
|
2020-04-15 12:28:20 +08:00
|
|
|
def _merge(root, t): # -> int
|
|
|
|
if root is None:
|
|
|
|
return t
|
|
|
|
if t is None:
|
|
|
|
return root
|
|
|
|
if root < t:
|
|
|
|
root, t = t, root
|
|
|
|
root.right = leftHeap._merge(root.right, t)
|
2018-07-08 23:28:29 +08:00
|
|
|
if root.left is None or root.right is None:
|
2020-04-15 12:28:20 +08:00
|
|
|
root.s = 1
|
2018-07-08 23:28:29 +08:00
|
|
|
if root.left is None:
|
2020-04-15 12:28:20 +08:00
|
|
|
root.left, root.right = root.right, None
|
2018-07-08 23:28:29 +08:00
|
|
|
else:
|
2020-04-15 12:28:20 +08:00
|
|
|
if root.left.s < root.right.s:
|
|
|
|
root.left, root.right = root.right, root.left
|
2018-07-08 23:28:29 +08:00
|
|
|
root.s = root.right.s+1
|
|
|
|
return root
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def insert(self, nd):
|
|
|
|
if not isinstance(nd, node):
|
|
|
|
nd = node(nd)
|
2018-07-08 23:28:29 +08:00
|
|
|
if self.root is None:
|
2020-04-15 12:28:20 +08:00
|
|
|
self.root = nd
|
2018-07-08 23:28:29 +08:00
|
|
|
return
|
2020-04-15 12:28:20 +08:00
|
|
|
if self.root == nd:
|
|
|
|
self.root.freq += 1
|
2018-07-08 23:28:29 +08:00
|
|
|
return
|
2020-04-15 12:28:20 +08:00
|
|
|
prt = self. _findPrt(self.root, nd, None)
|
2018-07-08 23:28:29 +08:00
|
|
|
if prt is None:
|
2020-04-15 12:28:20 +08:00
|
|
|
self.root = leftHeap._merge(self.root, nd)
|
2018-07-08 23:28:29 +08:00
|
|
|
else:
|
2020-04-15 12:28:20 +08:00
|
|
|
if prt.left == nd:
|
|
|
|
prt.left.freq += 1
|
|
|
|
else:
|
|
|
|
prt.right.freq += 1
|
|
|
|
|
|
|
|
def remove(self, nd):
|
|
|
|
if not isinstance(nd, node):
|
|
|
|
nd = node(nd)
|
|
|
|
if self.root == nd:
|
|
|
|
self.root = leftHeap._merge(self.root.left, self.root.right)
|
|
|
|
else:
|
|
|
|
prt = self._findPrt(self.root, nd, None)
|
2018-07-08 23:28:29 +08:00
|
|
|
if prt is not None:
|
2020-04-15 12:28:20 +08:00
|
|
|
if prt.left == nd:
|
|
|
|
prt.left = leftHeap._merge(prt.left.left, prt.left.right)
|
2018-07-08 23:28:29 +08:00
|
|
|
else:
|
2020-04-15 12:28:20 +08:00
|
|
|
prt.right = leftHeap._merge(
|
|
|
|
prt.right.left, prt.right.right)
|
|
|
|
|
|
|
|
def find(self, nd):
|
|
|
|
if not isinstance(nd, node):
|
|
|
|
nd = node(nd)
|
|
|
|
prt = self._findPrt(self.root, nd, self.root)
|
|
|
|
if prt is None or prt == nd:
|
|
|
|
return prt
|
|
|
|
elif prt.left == nd:
|
|
|
|
return prt.left
|
|
|
|
else:
|
|
|
|
return prt.right
|
|
|
|
|
|
|
|
def _findPrt(self, root, nd, parent):
|
|
|
|
if not isinstance(nd, node):
|
|
|
|
nd = node(nd)
|
|
|
|
if root is None or root < nd:
|
|
|
|
return None
|
|
|
|
if root == nd:
|
|
|
|
return parent
|
|
|
|
l = self._findPrt(root.left, nd, root)
|
|
|
|
return l if l is not None else self._findPrt(root.right, nd, root)
|
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
def getTop(self):
|
|
|
|
return self.root
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
def pop(self):
|
|
|
|
nd = self.root
|
|
|
|
self.remove(self.root.val)
|
|
|
|
return nd
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
def levelTraverse(self):
|
2020-04-15 12:28:20 +08:00
|
|
|
li = [(self.root, 0)]
|
|
|
|
cur = 0
|
2018-07-08 23:28:29 +08:00
|
|
|
while li:
|
2020-04-15 12:28:20 +08:00
|
|
|
nd, lv = li.pop(0)
|
|
|
|
if cur < lv:
|
|
|
|
cur = lv
|
2018-07-08 23:28:29 +08:00
|
|
|
print()
|
2020-04-15 12:28:20 +08:00
|
|
|
print(nd, end=' ')
|
|
|
|
else:
|
|
|
|
print(nd, end=' ')
|
|
|
|
if nd.left is not None:
|
|
|
|
li.append((nd.left, lv+1))
|
|
|
|
if nd.right is not None:
|
|
|
|
li.append((nd.right, lv+1))
|
|
|
|
|
2018-07-08 23:28:29 +08:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
lh = leftHeap()
|
|
|
|
data = [(i-3)**2 for i in range(20)]
|
|
|
|
for i in data:
|
|
|
|
lh . insert(i)
|
|
|
|
lh.levelTraverse()
|
|
|
|
print()
|
|
|
|
for i in data:
|
|
|
|
print(lh.getTop())
|
2020-04-15 12:28:20 +08:00
|
|
|
if lh.find(i) is not None:
|
|
|
|
lh.remove(i)
|
2018-07-08 23:28:29 +08:00
|
|
|
'''
|
|
|
|
data = [(i-10)**2 for i in range(20)]
|
|
|
|
node(100,freq=1,s=3)
|
|
|
|
node(81,freq=2,s=3) node(64,freq=2,s=2)
|
|
|
|
node(16,freq=2,s=2) node(25,freq=2,s=2) node(49,freq=2,s=1) node(36,freq=2,s=1)
|
|
|
|
node(9,freq=2,s=1) node(4,freq=2,s=1) node(1,freq=2,s=1) node(0,freq=1,s=1)
|
|
|
|
node(100,freq=1,s=3)
|
|
|
|
node(81,freq=2,s=3)
|
|
|
|
node(64,freq=2,s=2)
|
|
|
|
node(49,freq=2,s=1)
|
|
|
|
node(36,freq=2,s=3)
|
|
|
|
node(25,freq=2,s=2)
|
|
|
|
node(16,freq=2,s=2)
|
|
|
|
node(9,freq=2,s=1)
|
|
|
|
node(4,freq=2,s=2)
|
|
|
|
node(1,freq=2,s=1)
|
|
|
|
node(0,freq=1,s=1)
|
|
|
|
None
|
|
|
|
None
|
|
|
|
None
|
|
|
|
None
|
|
|
|
None
|
|
|
|
None
|
|
|
|
None
|
|
|
|
None
|
|
|
|
None
|
|
|
|
'''
|
|
|
|
|
|
|
|
'''
|
|
|
|
data = [(i-3)**2 for i in range(20)]
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(225,freq=1,s=1)
|
|
|
|
node(196,freq=1,s=1)
|
|
|
|
node(169,freq=1,s=1)
|
|
|
|
node(144,freq=1,s=1)
|
|
|
|
node(121,freq=1,s=1)
|
|
|
|
node(100,freq=1,s=1)
|
|
|
|
node(81,freq=1,s=1)
|
|
|
|
node(64,freq=1,s=1)
|
|
|
|
node(49,freq=1,s=1)
|
|
|
|
node(36,freq=1,s=1)
|
|
|
|
node(25,freq=1,s=1)
|
|
|
|
node(16,freq=1,s=1)
|
|
|
|
node(9,freq=2,s=2)
|
|
|
|
node(4,freq=2,s=1) node(1,freq=2,s=1)
|
|
|
|
node(0,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
node(256,freq=1,s=1)
|
|
|
|
'''
|