github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/rpheap/rank_pairing_heap.go (about) 1 package rpheap 2 3 type node struct { 4 item int64 5 left, next *node // 对于root,next用于循环链表,指向下一棵半树;对于非root,next指向右儿子 6 rank int 7 } 8 9 // Heap for rank pairing heap 10 // zero value is an empty heap 11 type Heap struct { 12 head *node // 指向循环链表的头部 13 size int 14 } 15 16 // New is ctor for Heap 17 func New() *Heap { 18 return &Heap{} 19 } 20 21 type heapInterface interface { 22 Insert(val int64) 23 FindMin() int64 24 // 传入的heap将清零 25 Meld(*Heap) 26 DeleteMin() int64 27 Size() int 28 Clear() 29 } 30 31 var _ heapInterface = (*Heap)(nil) 32 33 // Insert into the heap 34 func (h *Heap) Insert(val int64) { 35 ptr := &node{item: val} 36 h.insertRoot(ptr) 37 h.size++ 38 } 39 40 func (h *Heap) insertRoot(ptr *node /*ptr 是根节点*/) { 41 if h.head == nil { // 第一棵半树 42 h.head = ptr 43 ptr.next = ptr // 循环链表 44 } else { 45 // 先把ptr串到header后面 46 ptr.next = h.head.next 47 h.head.next = ptr 48 // 如果ptr更小,将header指向ptr即可,这里体现了循环链表的灵活性 49 if ptr.item < h.head.item { 50 h.head = ptr 51 } 52 } 53 } 54 55 // FindMin from the heap 56 func (h *Heap) FindMin() int64 { 57 if h.head == nil { 58 panic("FindMin on empty heap") 59 } 60 return h.head.item 61 } 62 63 // Meld two heaps 64 func (h *Heap) Meld(a *Heap) { 65 if h.head == nil { 66 h.head = a.head 67 h.size = a.size 68 a.Clear() 69 return 70 } 71 if a.head == nil { 72 return 73 } 74 75 // 两个heap都非空 76 if h.head.item < a.head.item { 77 merge(h, a) 78 } else { 79 merge(a, h) 80 h.head = a.head 81 h.size = a.size 82 } 83 84 a.Clear() 85 return 86 } 87 88 func merge(a, b *Heap) { 89 // 前置条件是a、b非空 90 // 将b往a合并, 循环链表需要对长度为1的情况特殊处理下 91 if a.size == 1 { 92 ptr := a.head 93 ptr.next = nil 94 if ptr.left != nil || ptr.rank != 0 { 95 panic("size 1 heap with left or non-zero rank") 96 } 97 b.insertRoot(ptr) 98 b.size++ 99 a.head = b.head 100 a.size = b.size 101 return 102 } else if b.size == 1 { 103 ptr := b.head 104 ptr.next = nil 105 if ptr.left != nil || ptr.rank != 0 { 106 panic("size 1 heap with left or non-zero rank") 107 } 108 a.insertRoot(ptr) 109 a.size++ 110 return 111 } 112 113 // 两个链表长度都大于1 114 // 将b的第二个元素串到a的第一个元素后面 115 // 同时将a原先的第二个元素串到b的第一个元素后面 116 // 这样b的第二个元素最终会回到b的第一个元素,然后再到a原先的第二个元素,直到回到a的头部 117 // 便把两个链表合并了 118 a.head.next, b.head.next = b.head.next, a.head.next 119 a.size += b.size 120 121 } 122 123 // DeleteMin from the heap 124 func (h *Heap) DeleteMin() int64 { 125 if h.head == nil { 126 panic("DeleteMin on empty heap") 127 } 128 129 h.size-- 130 ret := h.head.item 131 132 bucket := make([]*node, h.maxBucketSize()) 133 // 沿着root的唯一左child一路往右(包括左child本身),将root所在的树分解成若干棵半树,并对相同rank的树进行合并 134 for ptr := h.head.left; ptr != nil; { 135 // 先记录下右child,因为ptr要作为独立半树进行合并,next必须置为空 136 nextPtr := ptr.next 137 ptr.next = nil 138 mergeSubTreeByRank(bucket, ptr) 139 ptr = nextPtr 140 } 141 // 遍历所有半树串成的循环链表,首棵树除外 142 for ptr := h.head.next; ptr != h.head; { 143 nextPtr := ptr.next 144 ptr.next = nil 145 mergeSubTreeByRank(bucket, ptr) 146 ptr = nextPtr 147 } 148 149 // 将bucket中的所有半树插入到空heap 150 h.head = nil 151 for _, ptr := range bucket { 152 if ptr != nil { 153 h.insertRoot(ptr) 154 } 155 } 156 return ret 157 } 158 159 func mergeSubTreeByRank(bucket []*node, ptr *node /*ptr 是根节点*/) { 160 for bucket[ptr.rank] != nil { 161 rank := ptr.rank 162 ptr = link(ptr, bucket[rank]) 163 bucket[rank] = nil 164 } 165 bucket[ptr.rank] = ptr 166 } 167 168 func link(a *node, b *node) *node { 169 // 前置条件是a、b都非空 170 var winner, loser *node 171 // 以a、b中较小的根作为合并后的半树的根 172 if a.item < b.item { 173 winner = a 174 loser = b 175 } else { 176 winner = b 177 loser = a 178 } 179 180 // 将胜出半树的左child挂到胜败半树的右child上(此前右child为空) 181 loser.next = winner.left 182 winner.left = loser 183 // 在此之前a、b的rank已经保证相等 184 winner.rank++ 185 return winner 186 } 187 188 func (h *Heap) maxBucketSize() int { 189 // 对于一n个元素的rpheap,rank最多是log n 190 // 对于type 1或type 2的rpheap,rank上限更低,这里简单起见按log n算 191 bit, cnt := 0, h.size 192 for cnt > 1 { 193 cnt /= 2 194 bit++ 195 } 196 return bit + 1 // [0, rank]共有rank+1个值 197 } 198 199 // Size of the heap 200 func (h *Heap) Size() int { 201 return h.size 202 } 203 204 // Clear the heap 205 func (h *Heap) Clear() { 206 h.head = nil 207 h.size = 0 208 }