|
| 1 | + |
| 2 | + |
| 3 | +# 小顶堆(Go) |
| 4 | + |
| 5 | +建堆有两种方式: |
| 6 | + |
| 7 | +1. 自顶向下,从第一个节点开始到最后一个节点遍历,按插入节点的方式建堆,节点的交换是从下往上的,时间复杂度是 `O(nlogn)` |
| 8 | +2. 自底向上,从倒数第一个非叶子节点开始,到第一个节点,节点的交换是从上往下的,时间复杂度是 `O(n)` |
| 9 | + |
| 10 | +堆的操作: |
| 11 | + |
| 12 | +1. 插入节点:将节点插入到数组尾,用将数组的尾节点从下往上的交换方式一直往上交换 |
| 13 | + |
| 14 | +2. 弹出堆顶:交换堆顶节点和数组最后一个节点,删除数组最后一个节点,接着将堆顶节点用从上往下的方式一直往下交换 |
| 15 | + |
| 16 | +```go |
| 17 | +package main |
| 18 | + |
| 19 | +import "fmt" |
| 20 | + |
| 21 | +func main() { |
| 22 | + h := heap{4, 6, 9, 1, 2, 3, 12, 34, 5, 6} |
| 23 | + h.init1() |
| 24 | + fmt.Println(h) |
| 25 | + h.insert(0) |
| 26 | + fmt.Println(h) |
| 27 | + h.pop() |
| 28 | + fmt.Println(h) |
| 29 | +} |
| 30 | + |
| 31 | +type heap []int |
| 32 | + |
| 33 | +func (h heap) swap(i, j int) { |
| 34 | + h[i], h[j] = h[j], h[i] |
| 35 | +} |
| 36 | + |
| 37 | +func (h heap) init1() { // bottom-up, O(n), 自底向上的建堆方式,节点的交换是从上往下的 |
| 38 | + for i := len(h)/2 - 1; i >= 0; i-- { |
| 39 | + h.topDown(i) |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +func (h heap) init2() { // top-down O(nlogn) 自顶向下的建堆方式,节点的交换是从下往上的 |
| 44 | + for i := 0; i < len(h); i++ { |
| 45 | + h.bottomUp(i) |
| 46 | + } |
| 47 | +} |
| 48 | + |
| 49 | +func (h *heap) insert(val int) { |
| 50 | + *h = append(*h, val) |
| 51 | + h.bottomUp(len(*h) - 1) |
| 52 | +} |
| 53 | + |
| 54 | +func (h heap) bottomUp(cur int) { |
| 55 | + parent := (cur+1)/2 - 1 |
| 56 | + for parent >= 0 { |
| 57 | + if h[cur] < h[parent] { |
| 58 | + h.swap(cur, parent) |
| 59 | + } else { |
| 60 | + break |
| 61 | + } |
| 62 | + cur = parent |
| 63 | + parent = (parent+1)/2 - 1 |
| 64 | + } |
| 65 | +} |
| 66 | + |
| 67 | +func (h heap) topDown(cur int) { |
| 68 | + minn := 2*cur + 1 |
| 69 | + for minn < len(h) { |
| 70 | + if 2*cur+2 < len(h) && h[2*cur+2] < h[minn] { |
| 71 | + minn = 2*cur + 2 |
| 72 | + } |
| 73 | + if h[cur] > h[minn] { |
| 74 | + h.swap(cur, minn) |
| 75 | + } else { |
| 76 | + break |
| 77 | + } |
| 78 | + cur = minn |
| 79 | + minn = 2*cur + 1 |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +func (h *heap) pop() int { |
| 84 | + h.swap(0, len(*h)-1) |
| 85 | + res := (*h)[len(*h)-1] |
| 86 | + *h = (*h)[:len(*h)-1] |
| 87 | + h.topDown(0) |
| 88 | + return res |
| 89 | +} |
| 90 | + |
| 91 | +``` |
| 92 | + |
| 93 | + |
| 94 | + |
| 95 | + |
| 96 | + |
| 97 | +# 大顶堆(Java) |
| 98 | + |
| 99 | +从第一个非叶子节点(若数组长度为 `size`,那么第一个非叶子节点的下标则为 `size / 2` )倒序遍历至第一个节点,每个循环中都与自身子节点中较大的子节点交换。 |
| 100 | + |
| 101 | +```java |
| 102 | +package src.DataStructure; |
| 103 | + |
| 104 | +public class Heap { |
| 105 | + |
| 106 | + private int[] arrays = new int[1000]; |
| 107 | + |
| 108 | + private int size; |
| 109 | + |
| 110 | + public Heap(int[] arrays){ |
| 111 | + this.size = arrays.length; |
| 112 | + System.arraycopy(arrays, 0, this.arrays, 0, size); |
| 113 | + heapify(size); |
| 114 | + } |
| 115 | + |
| 116 | + public void add(int value){ |
| 117 | + arrays[size++] = value; |
| 118 | + heapify(size); |
| 119 | + } |
| 120 | + |
| 121 | + |
| 122 | + public void heapify(int size){ |
| 123 | + for(int i = size / 2; i >= 0; i--){ |
| 124 | + sink(i); |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + public void sink(int index){ |
| 129 | + while(2 * index + 1 < size){ |
| 130 | + int temp = 2 * index + 1; |
| 131 | + if(temp + 1 < size && arrays[temp] < arrays[temp + 1]){ |
| 132 | + temp = temp + 1; |
| 133 | + } |
| 134 | + if(arrays[temp] <= arrays[index]){ |
| 135 | + break; |
| 136 | + } |
| 137 | + swap(arrays, index, temp); |
| 138 | + index = temp; |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + public int poll(){ |
| 143 | + int ans = arrays[0]; |
| 144 | + swap(arrays, 0, --size); |
| 145 | + heapify(size); |
| 146 | + return ans; |
| 147 | + } |
| 148 | + |
| 149 | + public void swap(int[] nums, int left, int right){ |
| 150 | + int temp = nums[left]; |
| 151 | + nums[left] = nums[right]; |
| 152 | + nums[right] = temp; |
| 153 | + } |
| 154 | + |
| 155 | + |
| 156 | + public static void main(String[] args) { |
| 157 | + int[] arrays = new int[]{6, 8, 10, 2, 4, 11, 13, 9, 1, 5, 7, 3}; |
| 158 | + Heap heap = new Heap(arrays); |
| 159 | + heap.add(200); |
| 160 | + while(heap.size != 0){ |
| 161 | + System.out.println(heap.poll()); |
| 162 | + } |
| 163 | + } |
| 164 | +} |
| 165 | + |
| 166 | +``` |
| 167 | + |
| 168 | + |
| 169 | + |
0 commit comments