package heap
import (
"encoding/json"
"fmt"
"testing"
)
type student struct {
Name string
Age int
Height int
Weight int
}
type MyHeap struct {
heap []*student
indexMap map[*student]int
heapSize int
comparator func(a, b *student) bool
}
func (my *MyHeap)String() string {
byte,_ := json.MarshalIndent(my.heap,"\t"," ")
return string(byte)
}
func NewMyHeap(com func(a, b *student) bool ) *MyHeap {
return &MyHeap{
heap: []*student{},
indexMap: map[*student]int{},
heapSize: 0,
comparator: com,
}
}
func (my *MyHeap) IsEmpty() bool {
return my.heapSize == 0
}
func (my *MyHeap) Size() int {
return my.heapSize
}
func (my *MyHeap)contains(key *student) bool {
_, ok := my.indexMap[key]
return ok
}
func (my *MyHeap)push(value *student) {
my.heap = append(my.heap, value)
my.indexMap[value] = my.heapSize
my.heapInsert(my.heapSize)
my.heapSize++
}
func (my *MyHeap)pop() *student {
ans := my.heap[0]
end := my.heapSize - 1
my.swap(0,end)
my.heap = my.heap[0:end]
delete(my.indexMap,ans)
my.heapSize--
my.heapify(0,my.heapSize)
return ans
}
func (my *MyHeap)heapInsert(index int){
for my.comparator(my.heap[index],my.heap[(index -1) /2]) {
my.swap(index,(index - 1) / 2)
index = (index - 1) / 2
}
}
func (my *MyHeap)resign(val *student) {
valueIndex := my.indexMap[val]
my.heapInsert(valueIndex)
my.heapify(valueIndex,my.heapSize)
}
func (my *MyHeap)heapify(index, heapSize int) {
leftChild := 2 * index + 1
for leftChild < heapSize {
best := leftChild
if leftChild + 1 < heapSize && my.comparator(my.heap[best + 1], my.heap[best]) {
best = leftChild + 1
}
if !my.comparator(my.heap[best],my.heap[index]) {
break
}
my.swap(index,best)
index = best
leftChild = 2 *index + 1
}
}
func (my *MyHeap)swap(i, j int) {
my.heap[i], my.heap[j] = my.heap[j],my.heap[i]
my.indexMap[my.heap[i]],my.indexMap[my.heap[j]] = my.indexMap[my.heap[j]],my.indexMap[my.heap[i]]
}
func TestMyHeap(t *testing.T) {
heap := NewMyHeap(func(a, b *student) bool {
if a == b {
return false
}
if a.Age > b.Age {
return true
}
if a.Age == b.Age {
return a.Height > b.Height
}
return false
})
students := []student{
{
Name: "五零",
Age: 50,
Height: 190,
Weight: 130,
},
{
Name: "张三",
Age: 40,
Height: 160,
Weight: 100,
},
{
Name: "李四",
Age: 15,
Height: 100,
Weight: 110,
},
{
Name: "王五",
Age: 19,
Height: 190,
Weight: 190,
},
{
Name: "李六",
Age: 19,
Height: 180,
Weight: 170,
},
}
heap.push(&students[0])
heap.push(&students[1])
heap.push(&students[2])
heap.push(&students[3])
heap.push(&students[4])
students[0].Age = 7
heap.resign(&students[0])
for !heap.IsEmpty() {
fmt.Println(heap.pop())
}
}
=== RUN TestMyHeap
&{张三 40 160 100}
&{王五 19 190 190}
&{李六 19 180 170}
&{李四 15 100 110}
&{五零 7 190 130}
--- PASS: TestMyHeap (0.00s)
PASS