算法系列(十)堆实现优先队列

来源:互联网 发布:网络言论自由的例子 编辑:程序博客网 时间:2024/06/04 19:17

在算法系列(九)平衡二叉查找树AVL树中介绍了AVL树。这篇文章主要讲解优先队列。

一般都使用二叉堆来实现优先队列。暂时之说这种实现。

堆的定义和性质

堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:

Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2]

即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。

堆分为大顶堆和小顶堆,满足Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆,

满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。

由上述性质可知大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。

堆的存储

一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。


堆的基本操作--插入删除


插入的策略叫做上滤,删除的策略叫做下滤。

堆排序

首先可以看到堆建好之后堆中第0个数据是堆中最小的数据。取出这个数据再执行下堆的删除操作。这样堆中第0个数据又是堆中最小的数据,重复上述步骤直至堆中只有一个数据时就直接取出这个数据。

代码实现

// 向堆中插入元素public static void insert(List heap, int value) {heap.add(value);// 开始上升操作heapUp2(heap, heap.size() - 1);// heapUp(heap, heap.size() - 1);}
// 非递归实现public static void heapUp2(List heap, int index) {int parent = 0;for (; index > 1; index /= 2) {// 获取index的父节点的下标parent = index / 2;// 获得父节点的值int parentValue = (Integer) heap.get(parent);// 获得index位置的值int indexValue = (Integer) heap.get(index);// 如果大于就交换if (parentValue > indexValue) {swap(heap, parent, index);}}}
/** * 删除堆中最小的值,也就是删除位置是1的值,也就是根节点的值 操作原理是:当删除根节点的数值时,原来的位置就会出现一个孔 * 填充这个孔的方法就是,把最后的叶子的值赋给该孔,最后把该叶子删除 *  * @param heap */public static void deleteMin(List heap) {// 把最后的一个叶子的数值赋值给1个位置heap.set(1, heap.get(heap.size() - 1));// 下滤操作heapDown2(heap, 1);// heapDown(heap, 1);// 把最后一个位置的数字删除heap.remove(heap.size() - 1);}
// 非递归实现public static void heapDown2(List heap, int index) {int child = 0;// 存储左儿子的位置int temp = (Integer) heap.get(index);int n = heap.size() - 2;// 如果有儿子的话for (; 2 * index <= n; index = child) {// 获取左儿子的位置child = 2 * index;// 如果只有左儿子if (child == n) {child = 2 * index;} // 如果右儿子比左儿子的数值小else if ((Integer) heap.get(child) > (Integer) heap.get(child + 1)) {child++;}// 如果数值最小的儿子比temp的值小if ((Integer) heap.get(child) < temp) {// 交换堆中的child,和index位置的值swap(heap, child, index);} else {break;}}}


算法实现代码github地址为https://github.com/robertjc/simplealgorithm

后续会不断补充,有些地方写的可能有问题,请多指教。


欢迎扫描二维码,关注我的公众账号



0 0
原创粉丝点击