zoukankan      html  css  js  c++  java
  • loserTree实现多路合并

    // k 路归并时间复杂度为 O(log2^m / log2^k * (k-1) * (n-1)) n为
    // 对n个外部文件进行外排,m为归并断个数     (k- 1) / log 2^k 随k的增长而增长
    // 因此内部采用 loser tree进行排序
    // 为什么不采用胜者树
    // 败者树是一个完全二叉树,非叶子节点记录失败者。那么相对于胜者树,具有访存小的优势。胜者树胜者拿走后,
    // 整条通路(从叶子到根)所有记录的胜者信息失效,那么新加入节点需要从叶子一直遍历到根,有可能每次都要
    // 写入(更新新的胜者)。而败者树,新加入的节点可以利用整条路径的败者信息。
    
    // 多路 merage 的实现 (只是简单把merage实现了,要排序还得递归再排)
    #include<bits/stdc++.h>
    #define rep(i, n) for(int i=0;i!=n;++i)
    #define per(i, n) for(int i=n-1;i>=0;--i)
    #define Rep(i, sta, n) for(int i=sta;i!=n;++i)
    #define rep1(i, n) for(int i=1;i<=n;++i)
    #define per1(i, n) for(int i=n;i>=1;--i)
    #define Rep1(i, sta, n) for(int i=sta;i<=n;++i)
    #define L rt<<1
    #define R rt<<1|1
    #define inf (0x3f3f3f3f)
    #define llinf (1e18)
    #define ALL(A) A.begin(),A.end()
    #define SIZE(A) ((int)A.size())
    #define MOD (1e9 + 7)
    #define PII pair<int,int>
    #define LEN 32
    typedef long long i64;
    using namespace std;
    struct Array{
    	vector<int> arr;
    	int pos;
    }*Arr;
    int k,Count;//k路进行merage
    int *LoserTree, *External;
    void adjust(int cur)
    {
    	int p = (cur + k) >> 1; // 当前节点的父节点
    	while(p > 0){
    		if(External[cur] > External[LoserTree[p]])
    			swap(cur,LoserTree[p]);//交换 小的值上浮比较,大的修改为父节点
    		p >>= 1;
    	}//cur 一定为最小的那个下标 放入缓存
    	LoserTree[0] = cur;
    }
    void CreateLoserTree()//创建败者树
    {
    	rep(i,k) LoserTree[i] = i;
    	per(i,k)	adjust(i);//调整每一个节点,构建败者树
    }
    void k_Merage()
    {
    	rep(i,k){
    		int pos = Arr[i].pos;
    		External[i] = Arr[i].arr[pos];//初始化数据块
    		++Arr[i].pos;
    	}
    	CreateLoserTree();
    	int index = 0;
    	while(index < Count){
    		int minIndex = LoserTree[0];// minIndex 为最小的归并的列
    		cout << External[minIndex] << " ";
    		++index;
    		if(Arr[minIndex].pos >= Arr[minIndex].arr.size())
    			External[minIndex] = inf;//对应的归并的列已经全部归并
    		else{
    			External[minIndex] = Arr[minIndex].arr[Arr[minIndex].pos];
    			++Arr[minIndex].pos;
    		}
    		adjust(minIndex);//调整对应的排列
    	}
    }
    int main() {
    	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    	int num,val;	cin >> k;
    	Arr = new Array[k];
    	rep(i,k){
    		cin >> num;
    		Count += num;
    		rep(j,num){
    			cin >> val;
    			Arr[i].arr.push_back(val);
    		}
    		Arr[i].pos = 0;
    	}
    	LoserTree = new int[k];
    	External = new int [k];
    
    	k_Merage();
    	return 0;
    }
    

      

  • 相关阅读:
    我学的是设计模式的视频教程——辛格尔顿,生成器VS工厂方法
    android在广播接收器BroadcastReceiver里面再进行发送广播,造成当前广播接收器不断循环执行问题
    Android 出现警告Exported service does not require permission
    Android中如何像 360 一样优雅的杀死后台服务而不启动
    Android下写一个永远不会被KILL掉的进程/服务
    android 程序防止被360或者系统给kill掉
    android如何让service不被杀死
    如何让自己的Android程序永不被系统kill
    TextView的一些高级应用(自定义字体、显示多种颜色、添加阴影)
    Android ListView的背景和黑色边缘化的问题
  • 原文地址:https://www.cnblogs.com/newstartCY/p/13654825.html
Copyright © 2011-2022 走看看