|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- encoding: utf-8 -*- |
| 3 | +# at016_priorqueue: 最大堆实现最大优先级队列 |
| 4 | +""" |
| 5 | + Topic: sample |
| 6 | + Desc : 最大堆实现最大优先级队列 |
| 7 | +""" |
| 8 | +import at014_heapsort as hsort |
| 9 | + |
| 10 | +__author__ = 'Xiong Neng' |
| 11 | + |
| 12 | + |
| 13 | +class Item(): |
| 14 | + def __init__(self, val, key, index=-1): |
| 15 | + self.val = val |
| 16 | + self.key = key |
| 17 | + self.index = index |
| 18 | + |
| 19 | + def __cmp__(self, other): |
| 20 | + if self.key > other.key: |
| 21 | + return 1 |
| 22 | + else: |
| 23 | + return -1 if self.key < other.key else 0 |
| 24 | + |
| 25 | + def __str__(self): |
| 26 | + return str((self.val, self.key, self.index)) |
| 27 | + |
| 28 | + |
| 29 | +def heapGetMax(heap): |
| 30 | + """返回最大优先队列中取最大值""" |
| 31 | + return heap.seq[0] |
| 32 | + |
| 33 | + |
| 34 | +def heapPopMax(heap): |
| 35 | + """弹出最大优先队列中取最大值并返回这个值""" |
| 36 | + if heap.heapSize < 1: |
| 37 | + return None |
| 38 | + re = heap.seq[0] |
| 39 | + heap.seq[0] = heap.seq[heap.heapSize - 1] # 尾上的弄到头上去 |
| 40 | + heap.heapSize -= 1 # heap的大小-1 |
| 41 | + __maxHeapify(heap, 0) # 然后再次将其构建为最大堆 |
| 42 | + return re |
| 43 | + |
| 44 | + |
| 45 | +def heapIncreaseKey(heap, item, newKey): |
| 46 | + """增加队列中元素item的key为新的newKey, key <= newKey""" |
| 47 | + if newKey < item.key: |
| 48 | + return |
| 49 | + item.key = newKey |
| 50 | + while True: |
| 51 | + tmpItem = item |
| 52 | + iindex = tmpItem.index |
| 53 | + pindex = ((tmpItem.index + 1) >> 1) - 1 |
| 54 | + if iindex > 0 and heap.seq[pindex] < tmpItem: |
| 55 | + heap.seq[iindex], heap.seq[pindex] = heap.seq[pindex], heap.seq[iindex] |
| 56 | + heap.seq[iindex].index, heap.seq[pindex].index = iindex, pindex |
| 57 | + else: |
| 58 | + break |
| 59 | + |
| 60 | + |
| 61 | +def heapInsert(heap, item): |
| 62 | + """最大优先队列中插入一条元素item,将其放入队列到最后一个位置, |
| 63 | + 然后调用heapIncreaseKey""" |
| 64 | + heap.heapSize += 1 |
| 65 | + item.index = heap.heapSize - 1 |
| 66 | + heap.seq[heap.heapSize - 1] = item |
| 67 | + heapIncreaseKey(heap, item, item.key) |
| 68 | + |
| 69 | + |
| 70 | +def __maxHeapify(heap, i): |
| 71 | + """ |
| 72 | + 前提是i的两棵子树left(i)和right(i)的二叉树都是最大堆了 |
| 73 | + 现在加入i节点后,要保持这个二叉树为最大堆的性质 |
| 74 | + heap: Heap数据结构 |
| 75 | + """ |
| 76 | + seq = heap.seq |
| 77 | + slen = heap.heapSize |
| 78 | + while True: |
| 79 | + left = (i << 1) + 1 |
| 80 | + right = (i + 1) << 1 |
| 81 | + if left < slen and seq[left] > seq[i]: |
| 82 | + largest = left |
| 83 | + else: |
| 84 | + largest = i |
| 85 | + if right < slen and seq[right] > seq[largest]: |
| 86 | + largest = right |
| 87 | + if largest != i: |
| 88 | + seq[largest], seq[i] = seq[i], seq[largest] |
| 89 | + seq[largest].index, seq[i].index = seq[i].index, seq[largest].index |
| 90 | + i = largest |
| 91 | + else: |
| 92 | + break |
| 93 | + |
| 94 | + |
| 95 | +def __buildMaxHeap(heap): |
| 96 | + """ |
| 97 | + 由完全二叉树的性质可知:对于 n/2..n-1为下标的元素,都是叶子节点, |
| 98 | + 那么可从下标floor((i+1)/2 - 1)开始往前到0的元素调用maxHeapify |
| 99 | + heap: Heap数据结构 |
| 100 | + """ |
| 101 | + slen = heap.heapSize |
| 102 | + for i in range(((slen + 1) >> 1) - 1, -1, -1): |
| 103 | + __maxHeapify(heap, i) |
| 104 | + for i in range(heap.heapSize): |
| 105 | + heap.seq[i].index = i |
| 106 | + |
| 107 | + |
| 108 | +if __name__ == '__main__': |
| 109 | + iSeq = [9, 7, 8, 10, 16, 3, 14, 2, 1, 4] |
| 110 | + iVal = ['9', '7', '8', '10', '16', '3', '14', '2', '1', '4'] |
| 111 | + iVal = [2 * k for k in iVal] |
| 112 | + pa = zip(iVal, iSeq) |
| 113 | + lastParm = [Item(v, k) for (v, k) in pa] |
| 114 | + lastParm.extend([None] * 100) |
| 115 | + heap = hsort.Heap(lastParm, len(iSeq), len(lastParm)) |
| 116 | + __buildMaxHeap(heap) |
| 117 | + print([str(k) for k in heap.seq if k]) |
| 118 | + |
| 119 | + heapInsert(heap, Item('Love', 13)) |
| 120 | + print([str(k) for k in heap.seq if k]) |
0 commit comments