type Interface interface { sort.Interface Push(x interface{}) // add x as element Len() Pop() interface{} // remove and return element Len() - 1. }
以及Push和Pop两个导出的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Push pushes the element x onto the heap. // The complexity is O(log n) where n = h.Len(). funcPush(h Interface, x interface{}) { h.Push(x) up(h, h.Len()-1) }
// Pop removes and returns the minimum element (according to Less) from the heap. // The complexity is O(log n) where n = h.Len(). // Pop is equivalent to Remove(h, 0). funcPop(h Interface)interface{} { n := h.Len() - 1 h.Swap(0, n) down(h, 0, n) return h.Pop() }
// This example demonstrates a priority queue built using the heap interface. package main
import ( "container/heap" "fmt" )
// An Item is something we manage in a priority queue. type Item struct { value string// The value of the item; arbitrary. priority int// The priority of the item in the queue. // The index is needed by update and is maintained by the heap.Interface methods. index int// The index of the item in the heap. }
// A PriorityQueue implements heap.Interface and holds Items. type PriorityQueue []*Item
func(pq PriorityQueue) Len() int { returnlen(pq) }
func(pq PriorityQueue) Less(i, j int) bool { // We want Pop to give us the highest, not lowest, priority so we use greater than here. return pq[i].priority > pq[j].priority }
// update modifies the priority and value of an Item in the queue. func(pq *PriorityQueue) update(item *Item, value string, priority int) { item.value = value item.priority = priority heap.Fix(pq, item.index) }
// This example creates a PriorityQueue with some items, adds and manipulates an item, // and then removes the items in priority order. funcExample_priorityQueue() { // Some items and their priorities. items := map[string]int{ "banana": 3, "apple": 2, "pear": 4, }
// Create a priority queue, put the items in it, and // establish the priority queue (heap) invariants. pq := make(PriorityQueue, len(items)) i := 0 for value, priority := range items { pq[i] = &Item{ value: value, priority: priority, index: i, } i++ } heap.Init(&pq)
// Insert a new item and then modify its priority. item := &Item{ value: "orange", priority: 1, } heap.Push(&pq, item) pq.update(item, item.value, 5)
// Take the items out; they arrive in decreasing priority order. for pq.Len() > 0 { item := heap.Pop(&pq).(*Item) fmt.Printf("%.2d:%s ", item.priority, item.value) } // Output: // 05:orange 04:pear 03:banana 02:apple }
// Init establishes the heap invariants required by the other routines in this package. // Init is idempotent with respect to the heap invariants // and may be called whenever the heap invariants may have been invalidated. // The complexity is O(n) where n = h.Len(). funcInit(h Interface) { // heapify n := h.Len() for i := n/2 - 1; i >= 0; i-- { down(h, i, n) } }
funcdown(h Interface, i0, n int) { // parent i := i0 // 也可以用递归的方式 for { // left child j1 := 2*i + 1 // if left child does not exist if j1 >= n || j1 < 0 { break } j := j1 // left child // if right child exist and smaller than left child if j2 := j1 + 1; j2 < n && h.Less(j2, j1) { j = j2 // = 2*i + 2 // right child } if !h.Less(j, i) { break } // parent swap with the smaller child h.Swap(i, j) i = j } }
// Push pushes the element x onto the heap. // The complexity is O(log n) where n = h.Len(). funcPush(h Interface, x interface{}) { h.Push(x) up(h, h.Len()-1) }
funcup(h Interface, j int) { for { i := (j - 1) / 2// parent if i == j || !h.Less(j, i) { break } h.Swap(i, j) j = i } }
// Pop removes and returns the minimum element (according to Less) from the heap. // The complexity is O(log n) where n = h.Len(). // Pop is equivalent to Remove(h, 0). funcPop(h Interface)interface{} { n := h.Len() - 1 h.Swap(0, n) down(h, 0, n) return h.Pop() }