classNode(object):"""the type of class stored in the hashmap, in case there are many same heights
in the heap, maintain the number"""
def __init__(self, id, num):
self.id= id #id means its id in heap array
self.num = num #number of same value in this id 处理重复元素
classHashHeap(object):def __init__(self, mode):
self.heap=[]
self.mode=mode
self.size=0
self.hash={}deftop(self):return self.heap[0] if len(self.heap) > 0 else0defisempty(self):return len(self.heap) ==0def _comparesmall(self, a, b): #compare function in different mode
if a <=b:if self.mode == 'min':returnTrueelse:returnFalseelse:if self.mode == 'min':returnFalseelse:returnTruedef _swap(self, idA, idB): #swap two values in heap, we also need to change
valA =self.heap[idA]
valB=self.heap[idB]
numA=self.hash[valA].num
numB=self.hash[valB].num
self.hash[valB]=Node(idA, numB)
self.hash[valA]=Node(idB, numA)
self.heap[idA], self.heap[idB]=self.heap[idB], self.heap[idA]def add(self, now): #the key, height in this place
self.size += 1
ifself.hash.get(now):
hashnow=self.hash[now]
self.hash[now]= Node(hashnow.id, hashnow.num + 1)else:
self.heap.append(now)
self.hash[now]= Node(len(self.heap) - 1,1)
self._siftup(len(self.heap)- 1)defdelete(self, now):
self.size-= 1hashnow=self.hash[now]
id=hashnow.id
num=hashnow.numif num == 1:
self._swap(id, len(self.heap)-1) #like the common delete operation
self.hash.pop(now)
self.heap.pop()if len(self.heap) >id:
self._siftup(id)
self._siftdown(id)else:
self.hash[now]= Node(id, num - 1)defparent(self, id):if id ==0:return -1
return (id - 1) / 2
def_siftup(self,id):while abs(id -1)/2 < id : #iterative version
parentId = (id - 1)/2 #这里非常tricky.
ifself._comparesmall(self.heap[parentId],self.heap[id]):break
else:
self._swap(id, parentId)
id=parentIddef _siftdown(self, id): #iterative version
while 2*id + 1
l= 2*id + 1r= l + 1small=idifself._comparesmall(self.heap[l], self.heap[id]):
small=lif r < len(self.heap) andself._comparesmall(self.heap[r], self.heap[small]):
small=rif small !=id:
self._swap(id, small)else:breakid= small