def _bubbleup(heap, pos): parentpos = (pos - 1) >> 1 if _on_min_level(pos): if parentpos >= 0 and heapq.cmp_lt(heap[parentpos], heap[pos]): heap[pos], heap[parentpos] = heap[parentpos], heap[pos] _bubbleup_max(heap, parentpos) else: _bubbleup_min(heap, pos) else: if parentpos >= 0 and heapq.cmp_lt(heap[pos], heap[parentpos]): heap[pos], heap[parentpos] = heap[parentpos], heap[pos] _bubbleup_min(heap, parentpos) else: _bubbleup_max(heap, pos)
def _maxindex(heap): if len(heap) == 0: raise IndexError() elif 0 < len(heap) < 3: return len(heap) - 1 else: return 2 if heapq.cmp_lt(heap[1], heap[2]) else 1
def decrease_key(heap, second, newitem): """ For a heap containing a entries that are tuples such that :code:`first, second = (float, (int, int, int))` search for a matching second entry, then decrease the key for that entry. Except for changes to accommodate the desired inputs, this is taken directly from heapq._siftdown. Returns: None """ # find the index corresponding to the second value for pos, entry in enumerate(heap): if entry[1] == second: break heap[pos] = newitem # Follow the path to the root, moving parents down until finding # a place newitem fits. while pos > 0: parentpos = (pos - 1) >> 1 parent = heap[parentpos] if cmp_lt(newitem, parent): heap[pos] = parent pos = parentpos continue break heap[pos] = newitem
def _bubbleup_max(heap, pos): grandparentpos = (((pos - 1) >> 1) - 1) >> 1 while grandparentpos > 0: if heapq.cmp_lt(heap[grandparentpos], heap[pos]): heap[pos], heap[grandparentpos] = heap[grandparentpos], heap[pos] pos = grandparentpos grandparentpos = (((pos - 1) >> 1) - 1) >> 1 continue break
def _trickledown_max(heap, pos): while 2*pos + 1 < len(heap): m = 2*pos + 1 for d in [2*pos + 2, 4*pos + 3, 4*pos + 4, 4*pos + 5, 4*pos + 6]: if d < len(heap) and heapq.cmp_lt(heap[m], heap[d]): m = d if m > 2*pos + 2: if heapq.cmp_lt(heap[pos], heap[m]): heap[m], heap[pos] = heap[pos], heap[m] if heapq.cmp_lt(heap[m], heap[(m-1)>>1]): heap[m], heap[(m-1) >> 1] = heap[(m-1) >> 1], heap[m] pos = m continue else: if heapq.cmp_lt(heap[pos], heap[m]): heap[m], heap[pos] = heap[pos], heap[m] break
def _my_siftdown(heap, startpos, pos): newitem = heap[pos] while pos > startpos: parentpos = (pos - 1) >> 1 parent = heap[parentpos] if heapq.cmp_lt(newitem, parent): heap[pos] = parent heap[pos][-1] = pos pos = parentpos continue break heap[pos] = newitem heap[pos][-1] = pos
def _my_siftup(heap, pos): endpos = len(heap) newitem = heap[pos] # Bubble up the smaller child until hitting a leaf. childpos = 2 * pos + 1 # leftmost child position while childpos < endpos: # Set childpos to index of smaller child. rightpos = childpos + 1 if rightpos < endpos and not heapq.cmp_lt(heap[childpos], heap[rightpos]): childpos = rightpos if not heapq.cmp_lt(heap[childpos], newitem): break # Move the smaller child up. heap[pos] = heap[childpos] heap[pos][-1] = pos pos = childpos childpos = 2 * pos + 1 # The leaf at pos is empty now. Put newitem there, and bubble it up # to its final resting place (by sifting its parents down). heap[pos] = newitem heap[pos][-1] = pos
def _trickledown_max(heap, pos): while 2 * pos + 1 < len(heap): m = 2 * pos + 1 for d in [ 2 * pos + 2, 4 * pos + 3, 4 * pos + 4, 4 * pos + 5, 4 * pos + 6 ]: if d < len(heap) and heapq.cmp_lt(heap[m], heap[d]): m = d if m > 2 * pos + 2: if heapq.cmp_lt(heap[pos], heap[m]): heap[m], heap[pos] = heap[pos], heap[m] if heapq.cmp_lt(heap[m], heap[(m - 1) >> 1]): heap[m], heap[(m - 1) >> 1] = heap[(m - 1) >> 1], heap[m] pos = m continue else: if heapq.cmp_lt(heap[pos], heap[m]): heap[m], heap[pos] = heap[pos], heap[m] break
def maxheappushpop(heap, item): """Fast version of a heappush followed by a heappop.""" if heap and heapq.cmp_lt(item, heap[0]): item, heap[0] = heap[0], item heapq._siftup_max(heap, 0) return item