src/pkg/container/heap/heap.go - The Go Programming Language

Golang

Source file src/pkg/container/heap/heap.go

     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	// highest-valued node in its subtree.
     8	//
     9	// A heap is a common way to implement a priority queue. To build a priority
    10	// queue, implement the Heap interface with the (negative) priority as the
    11	// ordering for the Less method, so Push adds items while Pop removes the
    12	// highest-priority item from the queue. The Examples include such an
    13	// implementation; the file example_test.go has the complete source.
    14	//
    15	package heap
    16	
    17	import "sort"
    18	
    19	// Any type that implements heap.Interface may be used as a
    20	// min-heap with the following invariants (established after
    21	// Init has been called or if the data is empty or sorted):
    22	//
    23	//	!h.Less(j, i) for 0 <= i < h.Len() and j = 2*i+1 or 2*i+2 and j < h.Len()
    24	//
    25	// Note that Push and Pop in this interface are for package heap's
    26	// implementation to call.  To add and remove things from the heap,
    27	// use heap.Push and heap.Pop.
    28	type Interface interface {
    29		sort.Interface
    30		Push(x interface{}) // add x as element Len()
    31		Pop() interface{}   // remove and return element Len() - 1.
    32	}
    33	
    34	// A heap must be initialized before any of the heap operations
    35	// can be used. Init is idempotent with respect to the heap invariants
    36	// and may be called whenever the heap invariants may have been invalidated.
    37	// Its complexity is O(n) where n = h.Len().
    38	//
    39	func Init(h Interface) {
    40		// heapify
    41		n := h.Len()
    42		for i := n/2 - 1; i >= 0; i-- {
    43			down(h, i, n)
    44		}
    45	}
    46	
    47	// Push pushes the element x onto the heap. The complexity is
    48	// O(log(n)) where n = h.Len().
    49	//
    50	func Push(h Interface, x interface{}) {
    51		h.Push(x)
    52		up(h, h.Len()-1)
    53	}
    54	
    55	// Pop removes the minimum element (according to Less) from the heap
    56	// and returns it. The complexity is O(log(n)) where n = h.Len().
    57	// Same as Remove(h, 0).
    58	//
    59	func Pop(h Interface) interface{} {
    60		n := h.Len() - 1
    61		h.Swap(0, n)
    62		down(h, 0, n)
    63		return h.Pop()
    64	}
    65	
    66	// Remove removes the element at index i from the heap.
    67	// The complexity is O(log(n)) where n = h.Len().
    68	//
    69	func Remove(h Interface, i int) interface{} {
    70		n := h.Len() - 1
    71		if n != i {
    72			h.Swap(i, n)
    73			down(h, i, n)
    74			up(h, i)
    75		}
    76		return h.Pop()
    77	}
    78	
    79	func up(h Interface, j int) {
    80		for {
    81			i := (j - 1) / 2 // parent
    82			if i == j || h.Less(i, j) {
    83				break
    84			}
    85			h.Swap(i, j)
    86			j = i
    87		}
    88	}
    89	
    90	func down(h Interface, i, n int) {
    91		for {
    92			j1 := 2*i + 1
    93			if j1 >= n {
    94				break
    95			}
    96			j := j1 // left child
    97			if j2 := j1 + 1; j2 < n && !h.Less(j1, j2) {
    98				j = j2 // = 2*i + 2  // right child
    99			}
   100			if h.Less(i, j) {
   101				break
   102			}
   103			h.Swap(i, j)
   104			i = j
   105		}
   106	}