• 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;
    }
    

      

  • 相关阅读:
    C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法
    PAT甲级1018留坑——第一个测试点未过(Dijikstar+Dfs)
    PAT甲级1019水题飘过
    微信该公众号提供的服务出现故障
    The valid characters are defined in RFC 7230 and RFC 3986
    eclipse中Web Deployment Assembly与build path作用
    Invalid bound statement (not found)
    springmvc获取bean
    mac/linux查询网络端口占用
    SiteMesh使用(2.4.2)
  • 原文地址:https://www.cnblogs.com/newstartCY/p/13654825.html
Copyright © 2020-2023  润新知