从源码出发认识 Golang 中的 heap

本文详细介绍了 Golang 中的 heap 包,包括 heap.Interface 接口,如何使用 Init、Push、Pop 等函数操作堆,并通过实例展示了如何实现堆排序。通过对源码的解析,揭示了 Push 和 Pop 方法背后的逻辑。
摘要由CSDN通过智能技术生成

目录

前言

heap 包源码解析

heap.Interface

操作堆的函数

实现堆排序

前言

        在平时刷 LeetCode 准备算法题的时候不可避免的会遇到利用大(小)根堆或优先队列(利用堆实现)实现的解法。在其他语言中或许有现成的优先队列数据结构(例如 C++ 中的 priority_queue)因此实现比较方便,但是在 Golang 中并没有现成的数据结构可以使用,需要利用 heap 包去实现堆。

        在看题解或其他人的 Golang 代码时,经常发现不同的实现方式,例如下面这种。

func smallestK(arr []int, k int) []int {
	if k == 0 {
		return nil
	}
	h := &hp{arr[:k]}
	heap.Init(h)
    ...
}

type hp struct{ sort.IntSlice }

func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
func (hp) Push(interface{})     {}
func (hp) Pop() (_ interface{}) { return }

        对于 heap 包不是很了解的话可能会很奇怪,Push 方法和 Pop 方法里面好像没有任何逻辑?难道只需要用这种抽象的方法去表示我的 hp 结构体实现了 Push 方法和 Pop 方法就可以实现一个堆了么(本菜鸡之前真的是这么理解的...)。    

        然而事实的真相并没有那么简单,提前剧透一下这么写的原因其实是因为在这道题目中并不需要使用到 Push 和 Pop 的代码逻辑所以实现时干脆不写逻辑了。一下子无法理解这个原因的话可以看完文章后回看理解。

heap 包源码解析

heap.Interface

        使用 heap 包构建一个堆第一步就是调用 heap.Init 函数,该函数长下面这样。

func Init(h Interface) {
	// heapify
	n := h.Len()
	for i := n/2 - 1; i >= 0; i-- {
		down(h, i, n)
	}
}

        函数内部的代码逻辑其实不重要&

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值