(二叉树)堆排序:HeapSort

通过阅读读英文版的《Algorithms》,弄懂了HeapSort。下面将自己对HeapSort的理解过程记录下来。 (为了简洁,使用术语“heap”代表“binary heap”)

定义: 二叉树堆(a binary heap) 是一组键的集合,按堆顺序排列在一个完整的二进制树中,按数组的级别顺序表示(不使用第一个条目)。

一、理解用数组表示的二叉树

数组表示的二叉树有两个非常简单、重要的定义:

一个大小为N的数组用完全二叉树表示,它的高为:lgN  

l g N = = l o g 2 N lgN==log_{2}N lgN==log2N

在堆中,父节点的角标为【k/2】,相应的,父节点的两个子节点的角标分别为【2k】和【2k+1】。

二叉树

二、理解堆排序的sink() 方法

/**
 *  a  数组;
 *  k   a的角标;
 *  N   为a的最大角标
 */
private void sink(Comparable[] a, int k, int N){
     while(k*2<=N){
         int j= k*2;
         // 获取较大值的角标 
         if(j<N && less(a[j-1],a[j])) j++;
         if(!less(a[k-1], a[j-1])) break;
         // 将较大值设置为父节点
         exch(a, k-1, j-1);
         k=j;
     }
}

三、理解 堆排序

该排序算法很明显的一个特点是:原地排序。
该排序算法的第二部分有点像选择排序,但它使用了非常少的的比较。
heapsort 的排序方法在时间和空间上都是最优的。它保证了在最坏的情况下使用最多2NlgN次比较和固定的空间。

但这种排序方法很少被使用,因为它比较差的缓存特性,数组项很少和临近的项进行比较。

public static void sort(Comparable[] a){
    int N = a.length;
    //  第一步: 对对进行初始化
    for(int k=N/2; k>=1;k--){
       sink(a, k, N);
    }
    // 第二步: 迭代将最大值放到末尾,并减小子堆的大小
    while (N>1){
      exch(a, 0, --N);
      sink(a, 1, N);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值