堆 堆排序 优先队列 图文详解(Golang实现)
引入 # 在实际应用中,我们经常需要从一组对象中查找 最大值 或 最小值 。当然我们可以每次都先排序,然后再进行查找,但是这种做法效率很低。哪么有没有一种特殊的数据结构,可以高效率的实现我们的需求呢,答案就是 堆(heap) 堆分为最小堆和最大堆,它们的性质相似,我们以最小堆为例子。 最小堆 # 举例 # 如上图所示,就为一个最小堆。 特性 # 是一棵完全二叉树 如果一颗二叉树的任何结点,或者是树叶,或者左右子树均非空,则这棵二叉树称做满二叉树(full binary tree) 如果一颗二叉树最多只有最下面的两层结点度数可以小于2,并且最下面一层的结点都集中在该层最左边的连续位置上,则此二叉树称做完全二叉树(complete binary tree) 局部有序 最小堆对应的完全二叉树中所有结点的值均不大于其左右子结点的值,且一个结点与其兄弟之间没有必然的联系 二叉搜索树中,左子 < 父 < 右子 存储结构 # 由于堆是一棵完全二叉树,所以我们可以用顺序结构来存储它,只需要计算简单的代数表达式,就能够非常方便的查找某个结点的父结点和子节点,既避免了使用指针来保持结构,又能高效的执行相应操作。 Copy 结点i的左子结点为2xi+1,右子结点为2xi+2 结点i的父节点为(i-1)/2 数据结构 # Copy // 本例为最小堆 // 最大堆只需要修改less函数即可 type