|
1 | 1 | # Heap - 堆
|
2 | 2 |
|
3 |
| -一般情况下,堆通常指的是**二叉堆**,**二叉堆**是一个近似**完全二叉树**的数据结构,**即披着二叉树羊皮的数组,**故使用数组来实现较为便利。子结点的键值或索引总是小于(或者大于)它的父节点,且每个节点的左右子树又是一个**二叉堆**(大根堆或者小根堆)。根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。**常被用作实现优先队列。** |
| 3 | +一般情况下,堆通常指的是**二叉堆**,**二叉堆**是一个近似**完全二叉树**的数据结构,但由于对二叉树平衡及插入/删除操作较为麻烦,二叉堆实际上使用数组来实现。即物理结构为数组,逻辑结构为完全二叉树。子结点的键值或索引总是小于(或者大于)它的父节点,且每个节点的左右子树又是一个**二叉堆**(大根堆或者小根堆)。根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。**常被用作实现优先队列。** |
4 | 4 |
|
5 | 5 | ## 特点
|
6 | 6 |
|
|
15 | 15 |
|
16 | 16 | 以大根堆为例,堆的常用操作如下。
|
17 | 17 |
|
18 |
| -1. 最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点 |
19 |
| -2. 创建最大堆(Build_Max_Heap):将堆所有数据重新排序 |
20 |
| -3. 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算 |
| 18 | +1. 最大堆调整:将堆的末端子节点作调整,使得子节点永远小于父节点 |
| 19 | +2. 创建最大堆:将堆所有数据重新排序 |
| 20 | +3. 堆排序:移除位于第一个数据的根节点,并做最大堆调整的递归运算 |
21 | 21 |
|
22 | 22 | 其中步骤1是给步骤2和3用的。
|
23 | 23 |
|
24 | 24 | 
|
25 | 25 |
|
26 |
| -## Python |
| 26 | +## 堆排实现 |
| 27 | + |
| 28 | +使用迭代实现也较为简单,注意索引值初始化和置位即可,尤其是记住最后一个索引的值 last,Java 的实现中 `pop()` 操作同时带有排序功能。 |
| 29 | + |
| 30 | +### Python |
27 | 31 |
|
28 | 32 | ```python
|
29 | 33 | class MaxHeap:
|
@@ -71,6 +75,85 @@ class MaxHeap:
|
71 | 75 | self._sink(self.heap, 0)
|
72 | 76 | return item
|
73 | 77 | ```
|
| 78 | + |
| 79 | +### Java |
| 80 | + |
| 81 | +```java |
| 82 | +/** |
| 83 | + * Created by billryan on 29/7/2018. |
| 84 | + */ |
| 85 | +public class MaxHeap { |
| 86 | + private final int MAX_N = 10; |
| 87 | + private final int[] heap = new int[MAX_N]; |
| 88 | + private int last = 0; |
| 89 | + |
| 90 | + public int getLast() { |
| 91 | + return last; |
| 92 | + } |
| 93 | + |
| 94 | + public void push(int x) { |
| 95 | + int i = last++; |
| 96 | + while (i > 0) { |
| 97 | + int p = (i - 1) / 2; |
| 98 | + if (heap[p] >= x) { |
| 99 | + break; |
| 100 | + } |
| 101 | + heap[i] = heap[p]; |
| 102 | + i = p; |
| 103 | + } |
| 104 | + heap[i] = x; |
| 105 | + } |
| 106 | + |
| 107 | + public int pop() { |
| 108 | + int result = heap[0]; |
| 109 | + int x = heap[--last]; |
| 110 | + heap[last] = result; |
| 111 | + |
| 112 | + int i = 0; |
| 113 | + while (2 * i + 1 < last) { |
| 114 | + int left = 2 * i + 1, right = 2 * i + 2, swap = left; |
| 115 | + if (right < last && heap[left] < heap[right]) { |
| 116 | + swap = right; |
| 117 | + } |
| 118 | + if (heap[swap] <= x) { |
| 119 | + break; |
| 120 | + } |
| 121 | + |
| 122 | + heap[i] = heap[swap]; |
| 123 | + i = swap; |
| 124 | + } |
| 125 | + heap[i] = x; |
| 126 | + |
| 127 | + return result; |
| 128 | + } |
| 129 | + |
| 130 | + @Override |
| 131 | + public String toString() { |
| 132 | + StringBuilder sb = new StringBuilder(); |
| 133 | + sb.append("heap array: "); |
| 134 | + for (int i : heap) { |
| 135 | + sb.append(String.format("%d, ", i)); |
| 136 | + } |
| 137 | + return sb.toString(); |
| 138 | + } |
| 139 | + |
| 140 | + public static void main(String[] args) { |
| 141 | + MaxHeap maxHeap = new MaxHeap(); |
| 142 | + |
| 143 | + int[] array = new int[]{6, 5, 3, 1, 8, 7, 2, 4, 10, 9}; |
| 144 | + for (int i : array) { |
| 145 | + maxHeap.push(i); |
| 146 | + System.out.println(maxHeap); |
| 147 | + } |
| 148 | + |
| 149 | + for (int i = maxHeap.getLast() - 1; i >= 0; i--) { |
| 150 | + System.out.println("pop max heap value: " + maxHeap.pop()); |
| 151 | + System.out.println(maxHeap); |
| 152 | + } |
| 153 | + } |
| 154 | +} |
| 155 | +``` |
| 156 | + |
74 | 157 | ## C++
|
75 | 158 | ```c++
|
76 | 159 | #ifndef HEAP_H
|
|
0 commit comments