zoukankan      html  css  js  c++  java
  • 败者树Java实现

    败者树在数据结构的课本上就有,它可以直接获得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性能好的工作站、服务器。

  • 相关阅读:
    Firefox常用插件
    给创业者的提醒
    Visual Studio 2005插件开发官方Demo下载
    Windows Media Player Firefox Plugin支持Server 2003
    【转】C++的64位整数
    【转】C++成员函数的内存分配问题
    【转】C++类的实例分布
    【转】 IntelliJ Idea 常用快捷键列表
    程序员必备神器
    程序员必备神器
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3000929.html
Copyright © 2011-2022 走看看