A Min Heap always keeps the smallest element at the root, making it ideal for quickly accessing or removing the smallest item in a changing dataset.
A Max Heap keeps the largest element at the root, making it perfect for quickly accessing or removing the largest item in a dataset.
package main import ( "container/heap" "fmt" ) type IntHeap []int func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *IntHeap) Push(x interface{}) { *h = append(*h, x.(int)) } func (h *IntHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } func main() { h := &IntHeap{} heap.Init(h) heap.Push(h, 7) heap.Push(h, 3) heap.Push(h, 5) heap.Push(h, 1) for h.Len() > 0 { fmt.Print(heap.Pop(h)) if h.Len() > 0 { fmt.Print(" -> ") } } fmt.Println(" -> null") }
After inserting 7, 3, 5, 1 into a Min Heap, popping elements one by one returns them in ascending order: 1, 3, 5, 7.
package main import ( "container/heap" "fmt" ) type MaxHeap []int func (h MaxHeap) Len() int { return len(h) } func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] } func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *MaxHeap) Push(x interface{}) { *h = append(*h, x.(int)) } func (h *MaxHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } func main() { h := &MaxHeap{} heap.Init(h) heap.Push(h, 2) heap.Push(h, 9) heap.Push(h, 4) heap.Push(h, 6) for h.Len() > 0 { fmt.Print(heap.Pop(h)) if h.Len() > 0 { fmt.Print(" -> ") } } fmt.Println(" -> null") }
After inserting 2, 9, 4, 6 into a Max Heap, popping elements one by one returns them in descending order: 9, 6, 4, 2.
To maintain the median efficiently, use a Max Heap to store the smaller half of numbers and a Min Heap to store the larger half. This allows quick access to the middle values.
