堆排序

1 基础概念

堆,也叫 二叉堆,是一个数组,树的每个节点对应数组一个元素。

  1. 堆排序是利用 进行排序的
  2. 堆的左右儿子没有排序关系,只需要满足上父节点小于等于(或者大于等于)儿子就行
  3. 堆是一种完全二叉树:完全二叉树 是 一种除了最后一层之外的其他每一层都被完全填充,并且所有结点都保持向左对齐的树,向左对齐指的是儿子节点放置顺序左优先,这使得堆可以利用数组来表示(普通的一般的二叉树通常用链表作为基本容器表示)
  4. 堆有两种类型: 大根堆 小根堆
  5. 两种类型的概念如下:
    • 最大堆:每个结点的值都大于或等于左右孩子结点 A[PARENT(i)] ≥ A[i]
    • 最小堆:每个结点的值都小于或等于左右孩子结点 A[PARENT(i)] ≤ A[i]
    • 堆排序算法采用的是最大堆最小堆通常用于构造优先队列
  6. 最大堆:寻找数据流中最小的 k 个数字。
  7. 堆的高度为树根的高度:Θ(lgn)。堆结构上的一些基本操作的运行时间至多是与树的高度成正比。

给定下标 i,很容易计算其父节点、左节点和右节点:

def PARENT(i):
    return i / 2
def LEFT(i):
    return 2 * i
def RIGHT(i):
    return 2 * i + 1

堆节点的大小关系:
堆节点的大小关系

2 堆排序原理详解

堆排序原理:

  1. 首先将待排序的数组构造出一个最大堆
  2. 取出这个最大堆的堆顶节点(最大值),与堆的最下最右的元素进行交换,然后把剩下的元素再构造出一个最大堆;
  3. 重复第二步,直到这个最大堆的长度为1,此时完成排序

在堆中定义以下几种操作:

  1. 最大堆调整(Max-Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
  2. 创建最大堆(Build-Max-Heap):将堆中所有数据重新排序,使其成为最大堆
  3. 堆排序(Heap-Sort):移除位于第一个数据的根节点,并做最大堆调整的递归运算

2.1 最大堆调整(Max-Heapify)——维持堆的性质

MAX-HEAPIFY: 作用是保持最大堆的性质,是创建最大堆的核心子程序。输入为一个数组 A 和一个下标 i,A[i] 有可能小于其孩子,通过让 A[i] 在数组中 “逐层下降” ,从而使得以下标 i 为根节点的子树重新遵循最大堆的性质。

由于一次调整后,堆仍然违反堆性质,所以需要递归的测试,使得整个堆都满足堆性质。
MAX-HEAPIFY伪代码
算法图示 :
堆-最大化的图示
Python实现为:
注意:判断 左右儿子 的索引值,是否超出了数组的长度。

def MAX_HEAPIFY(A, i, size):
	l = LEFT(i)
    r = RIGHT(i)
    # 挑选出最大值对应的索引
    # 注意:"索引值-1" 来取出数字
	if l <= len(A) and A[l - 1] > A[i - 1]:
		largest = l
	else:
		largest = i
	if r <= len(A) and A[r - 1] > A[largest - 1]:
		largest = r
	else:
		largest = i
	if largest != i:
		# 将根节点与最大值点交换
        A[i - 1], A[largest - 1] = A[largest - 1], A[i - 1]
        # 递归进行堆最大化
        MAX_HEAPIFY(A, largest, size)

所以,在最差情况下(最底层恰好半满)运行时间为:
T ( n ) = T ( 2 n / 3 ) + Θ ( 1 ) T(n)=T(2n/3)+Θ(1) T(n)</

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值