码迷,mamicode.com
首页 > 编程语言 > 详细

堆排序

时间:2018-07-01 20:28:33      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:div   图片   alt   大数   amp   png   出现   研究   最好   

  科班出身的程序员就应该研究些算法和数据结构类的东西,不然,有什么优势?

  堆排序,结构是完全二叉树,选择排序的一种,其流程控制和冒泡排序类似,每次选出一个最大(或最小的元素)排出去,然后下一轮再选出一个最大(最小的),以此类推,直到剩下一个不能构成二叉树为止也排出去,排出来的就是有序的了。只不过每次选极值元素不是对所有元素都对比,而是心中模拟有一棵完全二叉树,每次选出最大顶(最小顶)。

  技术分享图片

原理解析:

  给定一个列表array=[16,7,3,20,17,8],对其进行堆排序。

  首先根据该数组元素构建一个完全二叉树,得到

技术分享图片

  然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:
  第一步: 初始化大顶堆(从最后一个有子节点开始往上调整最大堆)
技术分享图片技术分享图片技术分享图片

  20和16交换后导致16不满足堆的性质,因此需重新调整

技术分享图片

  这样就得到了初始堆。

  第二步: 堆顶元素R[1]与最后一个元素R[n]交换,交换后堆长度减一

  即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
技术分享图片

  第三步: 重新调整堆。此时3位于堆顶不满堆的性质,则需调整继续调整(从顶点开始往下调整)

技术分享图片技术分享图片

  重复上面的步骤:

技术分享图片技术分享图片技术分享图片

技术分享图片技术分享图片技术分享图片

技术分享图片技术分享图片

  注意了,现在你应该了解堆排序的思想了,给你一串列表,你也能写出&说出堆排序的过程。

  在写算法的过程中,刚开始我是很懵比。后来终于看懂了。请特别特别注意: 初始化大顶堆时 是从最后一个有子节点开始往上调整最大堆。而堆顶元素(最大数)与堆最后一个数交换后,需再次调整成大顶堆,此时是从上往下调整的。

  不管是初始大顶堆的从下往上调整,还是堆顶堆尾元素交换,每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换,交换之后都可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整。我在算法中是用一个while循环来解决的

参考代码:

 

时间复杂度:

  堆的存储表示是顺序的。因为堆所对应的二叉树为完全二叉树,而完全二叉树通常采用顺序存储方式。

  当想得到一个序列中第k个最小的元素之前的部分排序序列,最好采用堆排序。

  因为堆排序的时间复杂度是O(n+klog2n),若k≤n/log2n,则可得到的时间复杂度为O(n)

 算法稳定性:

  堆排序是一种不稳定的排序方法。

  因为在堆的调整过程中,关键字进行比较和交换所走的是该结点到叶子结点的一条路径,

  因此对于相同的关键字就可能出现排在后面的关键字被交换到前面来的情况。 

最后看一下排序家族

技术分享图片

 

 

堆排序

标签:div   图片   alt   大数   amp   png   出现   研究   最好   

原文地址:https://www.cnblogs.com/guanghe/p/9251056.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!