堆定制——2.0过度泛化版

package heap

import (
	"encoding/json"
	"fmt"
	"testing"
)

/*
什么时候需要手写堆,需要更新堆中的某些值,让他自然有序
迪杰斯特拉算法 就需要这类算法
从每个节点扫一遍, 代价会非常高
用户:可能对于某一个已经存在的对象,修改值,  在堆上找到,调整到该去的位置,logN级别
*/

type MyHeap struct {
	heap     []interface{}
	indexMap map[interface{}]int //任何一个样本,记录在堆上的位置
	heapSize int
	comparator func(a, b interface{}) bool //比大小
}

func (my *MyHeap)String() string {
	byt,_ := json.MarshalIndent(my.heap,"\t"," ")
	return string(byt)
}


func NewMyHeap(com func(a, b interface{}) bool ) *MyHeap {
	return &MyHeap{
		heap:       []interface{}{},
		indexMap:   map[interface{}]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 interface{}) bool {
	_, ok := my.indexMap[key]
	return ok
}

func (my *MyHeap)push(value interface{})  {
	my.heap = append(my.heap, value)
	my.indexMap[value] = my.heapSize
	my.heapInsert(my.heapSize)
	my.heapSize++
}

func (my *MyHeap)pop() interface{} {
	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 interface{})  {
	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]]
}


type student struct {
	Name   string
	Age    int
	Height int
	Weight int
}

func TestMyHeap(t *testing.T)  {
	heap := NewMyHeap(func(a, b interface{}) bool {  // 条件要统一
		if a == b {
			return false
		}

		A, B := a.(*student),b.(*student)
		if A.Age < B.Age {
			return  true
		}
		if A.Age == B.Age {
			return A.Height > B.Height //年龄相同根据身高排序
		}
		return false   // a.Age < b.Age
	})

	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 = 35
	students[0].Name = "XXOO"
	heap.resign(students[0])  //中途修改了某个值

	//fmt.Println(heap)

	for !heap.IsEmpty() {
		fmt.Println(heap.pop())
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

metabit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值