github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/mergesort/decimal64s/heap.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package heap provides heap operations for any type that implements 6 // heap.Interface. A heap is a tree with the property that each node is the 7 // minimum-valued node in its subtree. 8 // 9 // The minimum element in the tree is the root, at index 0. 10 // 11 // A heap is a common way to implement a priority queue. To build a priority 12 // queue, implement the Heap interface with the (negative) priority as the 13 // ordering for the Less method, so Push adds items while Pop removes the 14 // highest-priority item from the queue. The Examples include such an 15 // implementation; the file example_pq_test.go has the complete source. 16 package decimal64s 17 18 // Init establishes the heap invariants required by the other routines in this package. 19 // Init is idempotent with respect to the heap invariants 20 // and may be called whenever the heap invariants may have been invalidated. 21 // The complexity is Operator(n) where n = len(h). 22 func heapInit(h heapSlice) { 23 // heapify 24 n := len(h) 25 for i := n/2 - 1; i >= 0; i-- { 26 down(h, i, n) 27 } 28 } 29 30 // Push pushes the element x onto the heap. 31 // The complexity is Operator(log n) where n = len(h). 32 func heapPush(h *heapSlice, x heapElem) { 33 *h = append(*h, x) 34 up(*h, len(*h)-1) 35 } 36 37 // Pop removes and returns the minimum element (according to Less) from the heap. 38 // The complexity is Operator(log n) where n = len(h). 39 // Pop is equivalent to Remove(h, 0). 40 func heapPop(h *heapSlice) heapElem { 41 n := len(*h) - 1 42 (*h)[0], (*h)[n] = (*h)[n], (*h)[0] 43 down(*h, 0, n) 44 res := (*h)[n] 45 *h = (*h)[:n] 46 return res 47 } 48 49 func up(h heapSlice, j int) { 50 for { 51 i := (j - 1) / 2 // parent 52 if i == j || !h.Less(j, i) { 53 break 54 } 55 h.Swap(i, j) 56 j = i 57 } 58 } 59 60 func down(h heapSlice, i0, n int) bool { 61 i := i0 62 for { 63 j1 := 2*i + 1 64 if j1 >= n || j1 < 0 { // j1 < 0 after int overflow 65 break 66 } 67 j := j1 // left child 68 if j2 := j1 + 1; j2 < n && h.Less(j2, j1) { 69 j = j2 // = 2*i + 2 // right child 70 } 71 if !h.Less(j, i) { 72 break 73 } 74 h.Swap(i, j) 75 i = j 76 } 77 return i > i0 78 }