最小堆的时间复杂度_图解堆结构、堆排序及堆的应用

前言

这次我们介绍另一种时间复杂度为 O(nlogn) 的选择类排序方法叫做堆排序。

我将从以下几个方面介绍:

  • 堆的结构
  • 堆排序
  • 优化的堆排序
  • 原地堆排序
  • 堆的应用

堆的结构

什么是堆?我给出了百度的定义,如下:

堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵 完全二叉树 的数组对象。

堆总是满足下列性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值。
  • 堆总是一棵完全二叉树。

将根节点最大的堆叫做最大堆,根节点最小的堆叫做最小堆。

下图展示了一个最大堆的结构:

d855d6e04b2fa03498e9f5ae68acdcbf.png

可见,堆中某个节点的值总是小于等于其父节点的值。

由于堆是一棵完全二叉树,因此我们可以对每一层进行编号,如下:

2c1f912de34752bfb34665b620d51372.png

我们完全可以使用数组存放这些元素,那如何确定存放的位置呢?利用如下公式:

父节点:parent(i) = (i-1)/2

左孩子:leftChild(i) = 2*i+1
右孩子:rightChild(i) = 2*i+2

相关代码如下:

private int parent(int index) {    return (index - 1) / 2;}private int leftChild(int index) {    return index * 2 + 1;}private int rightChild(int index) {    return index * 2 + 2;}

添加元素

向堆中添加元素的步骤如下:

  1. 将新元素放到数组的末尾。
  2. 获取新元素的父亲节点在数组中的位置,比较新元素和父亲节点的值,如果父亲节点的值小于新元素的值,那么两者交换。以此类推,不断向上比较,直到根节点结束。

下图展示了添加元素的过程:

64aa546077a94ef5bf73602f748d1dfa.png

添加元素的过程也叫做 siftUp ,代码如下:

// Array是自己实现的动态数组private Array data;public void add(E e) {    data.addLast(e);    siftUp(data.getSize() - 1);}private void siftUp(int k) {    while (k > 0 && data.get(parent(k)).compareTo(data.get(k)) < 0) {        data.swap(k, parent(k));        k = parent(k);    }}

删除元素

删除元素其实就是删除堆顶的元素,步骤如下:

  1. 让数组最后一个元素和数组第一个元素(堆顶元素)交换。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值