Java实现-高效排序算法之堆排序

堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。

在处理堆排序时面临两个问题:一个是如何建堆。另一个是如何在输出堆顶后进行调整,成为一个新堆。

建堆的过程主要是通过在n/2(取下限)处开始,反复进行“筛选”的过程。具体过程见算法分析及注释。

//堆排序的伪代码
//heapsort(data[])
//    data转变成一个堆;
//    for i = data.length-1 downto 2
//        将根和i位置上的元素交换;
//        恢复树data[0],...,data[i-1]的堆属性;
public class Heapsort {
    public void heapsort(Object[] data){
        //将数组转换成一个堆
        for(int i = data.length/2-1; i >= 0; --i)
            moveDown(data, i, data.length-1);
        //实现位置的调整
        for(int i = data.length-1; i >= 1; --i){
            swap(data, 0, i);
            moveDown(data, 0, i-1);
        }
    }
    //将一个数组创建成一个堆(根元素沿着树向下移动的算法实现)
    void moveDown(Object[] data, int first, int last){
        int largest = 2*first +1;
        while(largest <= last){
            //first节点有两个孩子节点(2*first+1和2*first+2),
            //因此Comparable比较的是两个孩子节点的元素大小
            if(largest < last && 
            ((Comparable)data[largest]).compareTo(data[largest+1]) < 0)
            largest++;
            //比较根节点和最大节点处值的大小,如果满足条件,则交换值的大小,并且移动元素
            if(((Comparable)data[first]).compareTo(data[largest]) < 0){
                swap(data, first, last);
                first = largest;
                largest = 2*first +1;
            }
            else 
                //不满足堆的循环时,退出循环
                largest = last + 1;
        }
    }
    //实现数组中两个元素的交换
    void swap(Object[] a, int e1, int e2){
        Object tmp = a[e1];
        a[e1] = a[e2];
        a[e2] = tmp;
    }
}

堆排序在建堆的过程中heapsort()使用moveDown(),共执行O(n)步。第二步在调整的过程中是对logi在1到(n-1)上的和,即O(nlogn)。

在最好的情况下,堆排序比较的总次数为O(n)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值