go---堆实现,借助底层heap接口。数据流中的第 K 大元素

SDK中heap包中的接口,任何实现该接口的类型都可以作为堆

type Interface interface {
	sort.Interface
	Push(x interface{}) // add x as element Len()
	Pop() interface{}   // remove and return element Len() - 1.
}

自定义myHeap堆

//自定以堆
type myHeap []int

//实现heap接口
//1.实现sort包中的接口
func (h myHeap) Len() int           { return len(h) }
func (h myHeap) Less(i, j int) bool { return h[i] < h[j] } //小于号改变为大于号,变成大根堆
func (h myHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

//2.实现另外的两个方法
func (h *myHeap) Push(x interface{}) {
	fmt.Print("Push()被调用了:")
	*h = append(*h, x.(int))
}
func (h *myHeap) Pop() interface{} {
	fmt.Print("Pop()被调用了:")
	a := *h
	v := a[len(a)-1]
	*h = a[:len(a)-1] //切片长度减一
	return v
}
func Example_myHeap() {
	h := &myHeap{2, 1, 5}
	heap.Init(h)//对该类型进行初始化,相当于对切片重新修改为堆排序的状态。
	//注意:初始化之后堆就产生了
	fmt.Println(*h) //[5 1 2]
	heap.Push(h, 3) //调用heap包中提供的函数Init()、Push(),Pop(),就可以对我们的类型进行取堆顶,往堆中添加元素了
	fmt.Printf("minimum: %d\n", (*h)[0])
	for h.Len() > 0 {
		fmt.Printf("%d ", heap.Pop(h))
	}
	// Output:
	// minimum: 1
	// 1 2 3 5
	
}
func main() {
	Example_myHeap()
	/*
	Push()被调用了:minimum: 1                                       
	Pop()被调用了:1 Pop()被调用了:2 Pop()被调用了:3 Pop()被调用了:5 

	*/
}

再看一个栗子
在这里插入图片描述
这个是力扣上的一到需要用的算法题,我们可以直接使用上面的方法实现一个KthLargest类型的堆。

//结构体类型的堆
type KthLargest struct {
    sort.IntSlice
    //这个是sort包中的一个类型:type IntSlice []int,该类型实现了heap包中的sort.Interface接口。
    //可能是继承的关系,因此结构体也就不用实现sort包中的接口,我们只用实现另外的两个方法Pop(),Push()。
    k int
}

func Constructor(k int, nums []int) KthLargest {
    kl := KthLargest{k: k}
    for _, val := range nums {
        kl.Add(val)
    }
    return kl
}

func (kl *KthLargest) Push(v interface{}) {
    kl.IntSlice = append(kl.IntSlice, v.(int))
}

func (kl *KthLargest) Pop() interface{} {
    a := kl.IntSlice
    v := a[len(a)-1]
    kl.IntSlice = a[:len(a)-1]
    return v
}

func (kl *KthLargest) Add(val int) int {
    if (kl.myHeap).Len() >= kl.k {
		if val > kl.myHeap[0]{
			heap.Pop(&kl.myHeap)
			heap.Push(&kl.myHeap, val)
		}
	}else{
		heap.Push(&kl.myHeap, val)
	}
	//返回k个中最小的那个,也就是第k大的那个,因为k个元素是按照小根堆排序的,因此取出来堆顶就是我们最小的那个了,栈顶也就是切片的第一个元素
	return kl.myHeap[0]
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值