您的位置:首页 > 其它

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

2018-01-12 23:05 316 查看
堆排序

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;

索引优先队列

转:https://www.cnblogs.com/nullzx/p/6624731.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: