直接给出一个接口,满足接口的都可以实现为小顶堆(排序好的完全二叉树),因为接口又涉及到了 sort.Interface,顺便也给出源码。

    1. // src/container/heap/heap.go ---- line 21
    2. // The Interface type describes the requirements
    3. // for a type using the routines in this package.
    4. // Any type that implements it may be used as a
    5. // min-heap with the following invariants (established after
    6. // Init has been called or if the data is empty or sorted):
    7. //
    8. // !h.Less(j, i) for 0 <= i < h.Len() and 2*i+1 <= j <= 2*i+2 and j < h.Len()
    9. //
    10. // Note that Push and Pop in this interface are for package heap's
    11. // implementation to call. To add and remove things from the heap,
    12. // use heap.Push and heap.Pop.
    13. type Interface interface {
    14. sort.Interface
    15. Push(x interface{}) // add x as element Len()
    16. Pop() interface{} // remove and return element Len() - 1.
    17. }
    18. // src/sort/sort.go ---- line 11
    19. // A type, typically a collection, that satisfies sort.Interface can be
    20. // sorted by the routines in this package. The methods require that the
    21. // elements of the collection be enumerated by an integer index.
    22. type Interface interface {
    23. // Len is the number of elements in the collection.
    24. Len() int
    25. // Less reports whether the element with
    26. // index i should sort before the element with index j.
    27. Less(i, j int) bool
    28. // Swap swaps the elements with indexes i and j.
    29. Swap(i, j int)
    30. }

    除了接口,就只剩下七个神秘函数。对外公开的五个函数都基于剩下两个 private 函数,先分析一下这两个函数

    1. // src/container/heap/heap.go ---- line 90
    2. func up(h Interface, j int) {
    3. for {
    4. i := (j - 1) / 2 // parent
    5. if i == j || !h.Less(j, i) {
    6. break
    7. }
    8. h.Swap(i, j)
    9. j = i
    10. }
    11. }
    12. func down(h Interface, i0, n int) bool {
    13. i := i0
    14. for {
    15. j1 := 2*i + 1
    16. if j1 >= n || j1 < 0 { // j1 < 0 after int overflow
    17. break
    18. }
    19. j := j1 // left child
    20. if j2 := j1 + 1; j2 < n && h.Less(j2, j1) {
    21. j = j2 // = 2*i + 2 // right child
    22. }
    23. if !h.Less(j, i) {
    24. break
    25. }
    26. h.Swap(i, j)
    27. i = j
    28. }
    29. return i > i0
    30. }