随笔2019-4-4

算法课

这一次归纳一下堆排序
堆排序是一种优先级队列的实现,近似完全二叉树
一个优先级队列可以有如下4种操作:

  • Insert(S, x): 插入元素x到S集合中
  • Max(S): 返回S中最大的元素
  • Extract_max(S): 和Max操作相似,但同时从S中去掉那个最大的元素,相当于pop
  • Increase_key(S, x, k): 将元素x的key值设为k

堆的实现

在敲代码时,一般用一个数组就可以看成一个堆。
有如下特性:

  • root of tree: 第一个元素
  • parent(i): 下标为i的元素的父节点为i / 2(PS: 奇数向下取整)
  • left_child(i): 下标为i的元素的左子节点为2i
  • right_child(i): 下标为i的元素的右子节点为2i+1
    实现一遍变可以很容易理解

最大堆的特性

一个节点的key 大于等于其children的key

堆操作

max_heapify: 对于一个root来说,其左子树和右子树都已经是最大堆了,而本身却不一定大于左子树和右子树的根,需要将其最大堆化

max_heapify(A, i)
if max(A[i], A[2i], A[2i+1]) != A[i]
  Exchange bigger Child(A[2i], A[2i+1])
  Until no more call

很容易知道max_heapify的时间花费为:O(lgn)

Build_max_heap(A):
  for i = n / 2 down to 1
    do max_heapify(A, i)

乍看之下,很容易以为Build_max_heap(A)的时间花费为:nlgn
然而仔细思考,一般来说是在倒数第二层开始max_heapify,而在倒数第二层进行这个操作的时候,是只花了O(1)的时间的。
所以倒数第L层的节点来说,耗时为O(L)时间。
设总数为n,n/4的节点在倒数第一层,n/8的节点在倒数第二层...
因此Total amount of work:
n/4O(1c) + n/8O(2c)+ n/16O(3c) + 1O(lgnC)
n/4=2^k
C2^k(\frac{1}{2^0}+\frac{2}{2^1}+\frac{3}{2^2} + ... + \frac{k+1}{2^k})
由极限思想知括号内的多项式的上界为一个常数
因此Total amount为O(C2^k)\Theta(n)

堆排序

  1. 从无序的数组执行Build_max_heap
  2. 找出最大元素A[0]
  3. 将A[0]和A[n-1]交换
  4. 从堆中释放A[n-1]
  5. max_heapify(A, 0)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我是一个没有故事的人。 朋友说你写的东西太空了吧,我点点头。脑子里仍然是一片空空——何以我要下笔呢? 好久之前吧,...
    余重山阅读 1,560评论 0 2
  • 1.早上阿展陪我去听讲座,不过因为第二节有课,所以没有听完全程。《新闻业转型观察》原来纸媒有过那么辉煌、待遇那么好...
    老莓莓阅读 1,540评论 0 1
  • Nombas 和 ScriptEase 大概在 1992 年,一家称作 Nombas 的公司开发了一种叫做 C 减...
    一直以来都很好阅读 2,286评论 0 0
  • 感悟: 本周是最有收获但又糟心的一周。收获是报名拆书课及第一次更文两篇,糟心的是本周颈椎病常常使我头昏脑胀! 学习...
    简书时间煮雨阅读 767评论 0 1
  • 网上对一些关于对称加密、非对称加密、数字签名、数字证书等文章虽然很多,但是没有深入研究过或者看过一点的人过段时间很...
    WEIJAVA阅读 3,759评论 0 1