算法:堆排序

Posted 小白学算法

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法:堆排序相关的知识,希望对你有一定的参考价值。

1算法分析


将待排序的n个元素按照堆的定义建初堆,并移除堆顶元素



调整剩余的元素序列(也就是去掉了堆顶元素的序列),将这n-1个元素重新建成一个新堆,再移除堆顶元素



重复执行步骤二,进行n-1次筛选,新筛选的堆会越来越小,最后所有的堆顶元素都会被移除,被移除的堆顶元素就是一个有序序列


这个过程总结起来就是先建初堆,去掉堆顶元素后重建堆
   下图中,是对{14,98,77,35,62,55}进行升序排列的过程



2算法实现


public class Sort {
   /* 建堆 */
   public static void sift(int[] r, int k, int m) {// r[k..m]是以r[k]为根的完全二叉树,r[m]是最后一个结点
       int temp = r[k];// 暂存根结点
       int i = k;
       int j = 2 * i + 1;// a[j]是a[i]的左节点
       boolean finished = false;
       while (j < m && !finished) {
           /* 如果存在右子树,并且右子树大,那么就沿右分支筛选 */
           if (j + 1 < m && r[j] < r[j + 1]) {
               j += 1;
           }
           /* 不存在右子树或者根节点比左右子树都大的时候筛选完毕 */
           if (temp > r[j]) {
               finished = true;
           } else {
               r[i] = r[j];
               i = j;
               j = 2 * i + 1;
           } /* 继续筛选 */
       }
       r[i] = temp;
   }/* sift */
   /* 建初堆 */
   public static void heap(int[] r) {
       int len = r.length;
       for (int i = len / 2 - 1; i >= 0; i--) {
           sift(r, i, len);
       }
   }/* heap */
   public static void heapSort(int[] r) {
       int len = r.length;
       heap(r);
       /* 重建堆 */
       for (int m = len - 1; m > 0; m--) {
           /* 堆顶元素与堆尾交换 */
           int b = r[0];
           r[0] = r[m];
           r[m] = b;
           sift(r, 0, m);
       }
   }/* heapSort */
   public static void main(String[] args) {
       int[] r = { 14, 98, 77, 35, 62, 55 };
       Sort.heapSort(r);
       for (int i : r) {
           System.out.print(i + " ");
       }
   }
}


3算法分析




堆排序是我们所知的唯一能够同时最优地利用空间和时间的方法,他的的时间主要耗费在建初堆和重建堆上,如果有n个元素,建初堆需调整的次数最多为4n次,时间复杂度为O(n),调整堆的次数不超过2n[log2(n)],所以堆排序在最坏情况下,时间复杂度为O(nlog2(n)),空间复杂度为O(1),但它是不稳定排序





以上是关于算法:堆排序的主要内容,如果未能解决你的问题,请参考以下文章

堆排序算法的实现

7.2堆排序的代码分析(算法基础—排序算法)

选择排序(简单选择排序堆排序的算法思想及代码实现)

算法-java代码实现堆排序

『算法设计_伪代码』堆排序

十大经典排序算法总结(堆排序)