算法 2.4节 堆排序及其改进、索引优先队列

  • 堆排序
public class Heap {

    public static void sort(Comparable[] pq) {
        int N = pq.length;
        for (int k = N/2; k >=1; k --)
            sink(pq, k, N);
        while (N > 1) {
            exch(pq, 1, N--);
            sink(pq, 1, N);
        }
        }

    private static void sink(Comparable[] pq, int k, int n) {
        while (2*k <= n) {
            int j = 2*k;
            if (j < n && less(pq, j, j+1)) j++;
            if (!less(pq, k, j)) break;
            exch(pq, k, j);
            k = j;
        }
    }

    private static boolean less(Comparable[] pq, int i, int j) {
        return pq[i-1].compareTo(pq[j-1]) < 0;
    }

    private static void exch(Object[] pq, int i, int j) {
        Object swap = pq[i-1];
        pq[i-1] = pq[j-1];
        pq[j-1] = swap;
    }
    }
}
  • 改进

堆排序如果遇到“比较”的成本特别大的时候,还可以采用如下的方法
在《算法》中,考虑到处在数组尾部的元素一般都是比较小的元素,这样我们在把它放到堆顶后进行sink,一般它还是会下来的,那么我们为什么不直接将这个元素放到堆尾然后在swim上去呢?这样会减少很多次的比较,具体做法如下:
1.当我们将堆顶的元素放在数组尾部后,我们利用辅助空间暂时存储之前的堆尾元素temp,并不是将它放在堆顶;
2.现在堆顶是空的,我们不将temp放在上面,而是直接将堆顶对应的子节点中较大的那个节点bigger直接放上去(这样我们只需要比较一次哪个子节点大就可以了),然后这个bigger的位置就产生了空缺;
3.这个空缺的左右子节点继续比较产生较大的节点bigger`放在父节点空缺的位置上;
4.依次类推直到空缺的节点没有子节点;
5.将空缺的节点放上temp;
6.swim上浮
这个方法需要一个辅助空间,如果条件允许的话便可以用;而这种方法产生的比较次数几乎就成为了N;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值