败者树的Java实现

来源:互联网 发布:最优化导论pdf百度云 编辑:程序博客网 时间:2024/06/07 16:27

败者树在数据结构的课本上就有,它可以直接获得k个记录中的最小值/最大值,并且调整的时间复杂度为log(k),因此可以在多路归并排序中用来加速多个多并段中最小值/最大值的查找,从而提高归并的速度。

败者树的Java代码如下,其中的Result是待排记录的抽象:

/* * ResultSet.java     0.0.1 2013/04/04  * Copyright(C) 2013 db-iir RUC. All rights reserved.  */import java.util.ArrayList;/**  * This Class implements the loser tree algorithm. *  * @author  Hank Bian (bianhaoqiong@163.com) * @version 0.0.1, 2013/04/04 */public class LoserTree{private int[] tree = null;// 以顺序存储方式保存所有非叶子结点private int size = 0;private ArrayList<Result> leaves = null;// 叶子节点public LoserTree(ArrayList<Result> initResults){this.leaves = initResults;this.size = initResults.size();this.tree = new int[size];for (int i = 0; i < size; ++i){tree[i] = -1;}for (int i = size - 1; i >= 0; --i){adjust(i);}}public void del(int s){leaves.remove(s);size--;tree = new int[size];for (int i = 0; i < size; ++i){tree[i] = -1;}for (int i = size - 1; i >= 0; --i){adjust(i);}}public void add(Result leaf, int s){leaves.set(s, leaf);// 调整叶子结点adjust(s);// 调整非叶子结点}public Result getLeaf(int i){return leaves.get(i);}public int getWinner(){return tree[0];}private void adjust(int s){// s指向当前的值最小的叶子结点(胜者)int t = (s + size) / 2;// t是s的双亲while (t > 0){if (s >= 0&& (tree[t] == -1 || leaves.get(s).compareTo(leaves.get(tree[t])) > 0)){// 将树中的当前结点指向其子树中值最小的叶子int tmp = s;s = tree[t];tree[t] = tmp;}t /= 2;}tree[0] = s;// 树根指向胜者}}

在产生初始归并段时,使用ArrayList和Collections.sort()就可以了,这个是一种改进的归并内部排序算法,我试验过,效率很高的,给13个100万条的字符串列表(每个字符串约10个字符、有重复)排序,在四核3.2GhzCPU的机器上、单线程也只用了十秒钟而已。其实外排很大一部分的时间消耗在IO上,特别是对于CPU性能好的工作站、服务器。

原创粉丝点击