package maxheap import ( "reflect" "../array" ) type MaxHeap struct { data *array.Array } func New() *MaxHeap { return &MaxHeap{ data: array.New(20), } } func (a *MaxHeap) GetSize() int { return a.data.GetSize() } func parent(index int) int { return (index - 1) / 2 } func leftChild(index int) int { return index*2 + 1 } func rightChild(index int) int { return index*2 + 2 } func (h *MaxHeap) Add(e interface{}) { h.data.AddLast(e) h.siftUp(h.data.GetSize() - 1) } func (a *MaxHeap) siftUp(k int) { for k > 0 && Compare(a.data.Get(k), a.data.Get(parent(k))) > 0 { a.data.Swap(k, parent(k)) k = parent(k) } } func (a *MaxHeap) FindMax() interface{} { if a.data.GetSize() == 0 { panic("cannot findMax when heap is empty.") } return a.data.Get(0) } func (h *MaxHeap) ExtractMax() interface{} { ret := h.FindMax() h.data.Swap(0, h.data.GetSize()-1) h.data.RemoveLast() h.siftDown(0) return ret } func (a *MaxHeap) siftDown(k int) { for leftChild(k) < a.data.GetSize() { j := leftChild(k) if j+1 < a.data.GetSize() && Compare(a.data.Get(j+1), a.data.Get(j)) > 0 { j++ } if Compare(a.data.Get(k), a.data.Get(j)) > 0 { break } a.data.Swap(k, j) k = j } } func Compare(a interface{}, b interface{}) int { aType := reflect.TypeOf(a).String() bType := reflect.TypeOf(b).String() if aType != bType { panic("cannot compare different type params") } switch a.(type) { case int: if a.(int) > b.(int) { return 1 } else if a.(int) < b.(int) { return -1 } else { return 0 } case string: if a.(string) > b.(string) { return 1 } else if a.(string) < b.(string) { return -1 } else { return 0 } case float64: if a.(float64) > b.(float64) { return 1 } else if a.(float64) < b.(float64) { return -1 } else { return 0 } default: panic("unsupported type params") } }