1+ import heapPQ
2+
3+ class AdaptableHeapPQ (heapPQ ):
4+ """A locator based priority queue implemented with a binary heap"""
5+
6+ # Nested Locator class
7+ class Locator (heapPQ ._Item ):
8+ """Token for locating an entry of the priority queue"""
9+ __slots__ = '_index' #add index as additional filed
10+
11+ def __init__ (self , k ,v , j ):
12+ super ().__init__ (k ,v )
13+ self ._index = j
14+
15+ #### Non public behaviors
16+
17+ #Override swap to record new indices
18+ def _swap (self , i , j ):
19+ super ()._swap (i ,j ) # perform the swap
20+ self ._data [i ]._index = i #reset locator index (post swap)
21+ self ._data [j ]._index = j #reset locator index post swap
22+
23+ def _bubble (self , j ):
24+ if j > 0 and self ._data [j ] < self ._data [self ._parent (j )]:
25+ self ._upheap (j )
26+ else :
27+ self ._downheap (j )
28+
29+ def add (self , key , value ):
30+ """Add a key value pair"""
31+ token = self .Locator (key , value , len (self ._data )) #initialize locator index
32+ self ._data .append (token )
33+ self ._upheap (len (self ._data )- 1 )
34+
35+ return token
36+
37+ def update (self , loc , newkey , newval ):
38+ """Update the key and value for the entry identified by Locator loc"""
39+
40+ j = loc ._index
41+
42+ if not (0 <= j <= len (self ) and self ._data [j ] is loc ):
43+ raise ValueError ('Invalid Locator' )
44+
45+ loc ._key = newkey
46+ loc ._value = newval
47+
48+ self ._bubble (j )
49+
50+ def remove (self , loc ):
51+ """Remove and return k,v pair identified by Locator loc"""
52+
53+ j = loc ._index
54+ if not (0 <= j <= len (self ) and self ._data [j ] is loc ):
55+ raise ValueError ("Invalid locator" )
56+
57+ if j == len (self ) - 1 : #item at last position
58+ self ._data .pop () #just remove it
59+ else :
60+ self ._swap (j , len (self ) - 1 ) # swap item to the last position
61+ self ._data .pop () #remove it from the list
62+ self ._bubble (j ) #fix item displaced by the swap
63+
64+ return (loc ._key , loc ._value )
0 commit comments