losertree

#include <iostream>
#include <fstream>
#include<string.h>
#include<algorithm>
#include<queue>
const int inf = 1e8;
using namespace std;
int maxorder = 0;
struct runnode
{
    int value;
    int order;
    runnode(int v,int o):value(v),order(o){};
    runnode():value(0),order(0){};
    bool operator< (const runnode& p)
    {
        if(order!=p.order) return order<p.order;
        else return value<p.value;
    }
    bool operator> (const runnode& p)
    {
        if(order!=p.order) return order>p.order;
        else return value>p.value;
    }
    bool operator=(const runnode& r)
    {
        value = r.value;
        order = r.order;
    }

};
struct comprunnode
{
    int value;
    int order;
    comprunnode(int v,int o):value(v),order(o){};
    comprunnode():value(0),order(0){};
    bool operator< (const comprunnode& p)
    {
        return value<p.value;
    }
    bool operator> (const comprunnode& p)
    {
         return value>p.value;
    }
    bool operator=(const comprunnode& r)
    {
        value = r.value;
        order = r.order;
    }
};
runnode initialbuffer[105];
queue<comprunnode> buffer[1000];
template<class T>
class LoserTree
{
public:
    void initial();
    LoserTree(int num,T* play);
    int Winner(){return (n)?B[0]:0;}
    void replay(int i,T change);

    int n;
    int LowExt;
    int offset;
    int *B;
    T* L;
    void play(int p,int lc,int rc);
};
template<class T>
void LoserTree<T>::replay(int i,T change)
{
    L[i] = change;
    int p;
    if(i<=LowExt)
        p=(i+offset)/2;
    else
        p=(i-LowExt+n-1)/2;
    B[0] = L[i]>L[B[p]]?B[p]:i;
    B[p] = L[i]>L[B[p]]?i:B[p];
    for(;(p/2)>=1;p/=2)
    {
        int tmp = L[B[0]]>L[B[p/2]]?B[p/2]:B[0];
        B[p/2] = L[B[0]]>L[B[p/2]]?B[0]:B[p/2];
        B[0] = tmp;
    }
}
template<class T>
LoserTree<T>::LoserTree(int num,T* play)
{
    int s;
    n=num;
    for(s=1;2*s<=n-1;s+=s);
    LowExt = 2*(n-s);
    offset = 2*s-1;
    B = new int [num];
    L = new T [num+1];
    for(int i = 1;i<=num;i++)
    {
        L[i] = play[i];
    }
}
template<class T>
void LoserTree<T>::initial()
{
    int i;
    for(i=2;i<=LowExt;i+=2)
        play((offset+i)/2,i-1,i);
    if(n%2)
    {
        play(n/2,B[(n-1)/2],LowExt+1);
        i = LowExt+3;
    }
    else i=LowExt+2;
    for(;i<=n;i+=2)
        play((i-LowExt+n-1)/2,i-1,i);
}
template<class T>
void LoserTree<T>::play(int p,int lc,int rc)
{
    B[p] = L[lc]>L[rc]?lc:rc;
    int tmp1,tmp2;
    tmp1 = L[lc]>L[rc]?rc:lc;
    while(p>1&&p%2)
    {
        tmp2 = L[tmp1]>L[B[p/2]]?B[p/2]:tmp1;
        B[p/2] = L[tmp1]>L[B[p/2]]?tmp1:B[p/2];
        tmp1 = tmp2;
        p/=2;
    }
    B[p/2] = tmp1;
}
void putrunNode(runnode& r)
{
    fstream f;
    char data_name[20];
    sprintf(data_name, "%d%s",r.order, ".txt");
    f.open(data_name, ios::app);
    f<<r.value<<endl;
    f.close();
    maxorder = max(r.order,maxorder);
}
void putcomprunnode(comprunnode& c)
{
    fstream f;
    f.open("ans.txt",ios::app);
    f<<c.value<<endl;
    f.close();
}
int main()
{
    fstream f;
    f.open("Data.txt", ios::in);
    for(int i=1;i<=100;i++)
    {
        f>>initialbuffer[i].value;
        initialbuffer[i].order = 1;
    }
    LoserTree<runnode> LT(100,initialbuffer);
    LT.initial();
    int v;
    while(f>>v)
    {
        int o,index = LT.Winner();
        putrunNode(LT.L[index]);
        if(v>=LT.L[index].value)
            o = LT.L[index].order;
        else
            o = LT.L[index].order+1;
        runnode tmp(v,o);
        LT.replay(index,tmp);
    }
    f.close();
    for(int i = 1;i<=100;i++)
    {
        int v,o,index = LT.Winner();
        putrunNode(LT.L[index]);
        runnode tmp(inf,inf);
        LT.replay(index,tmp);
    }
//    //生成顺串结束,开始归并
    cout<<maxorder<<endl;
    fstream ff[maxorder+1];
    for(int i=1;i<=maxorder;i++)
    {
        char data_name[20];
        sprintf(data_name, "%d%s",i, ".txt");
        ff[i].open(data_name, ios::in);
    }
    comprunnode tmp[maxorder+1];
    for(int i=1;i<=maxorder;i++)
    {
        for(int j=1;j<=20;j++)
        {
            int a;
            ff[i]>>a;
            comprunnode cr(a,i);
            buffer[i].push(cr);
        }

    }
    for(int i=1;i<=maxorder;i++)
    {
        tmp[i] = buffer[i].front();
        buffer[i].pop();
    }
    LoserTree<comprunnode> LTree(maxorder,tmp);
    LTree.initial();
    while(true)
    {
        int tv = 0;
        int index = LTree.Winner();
        putcomprunnode(LTree.L[index]);
        int v,o = LTree.L[index].order;
        if(!buffer[o].empty())
        {
            v = buffer[o].front().value;
            buffer[o].pop();
            comprunnode tmp(v,o);
            LTree.replay(index,tmp);
        }
        else if(buffer[o].empty()&&!(ff[o]>>tv))
        {
            comprunnode tmp(inf,inf);
            LTree.replay(index,tmp);
        }
        else
        {
            comprunnode tmp(tv,o);
            LTree.replay(index,tmp);
            for(int i=1;i<=maxorder;i++)
            {
                int a;
                for(int j=1;j<=20-buffer[i].size()&&ff[i]>>a;j++)
                {
                    comprunnode cr(a,i);
                    buffer[i].push(cr);
                }
            }
        }
        bool flag = true;
        for(int i = 1;i<=maxorder;i++)
        {
            if(LTree.L[i].value!=inf)
                flag = false;
        }
        if(flag)
            break;
    }
    //处理剩余元素
//    for(int i = 1;i<=4;i++)
//    {
//        ff[i].close();
//        char data_name[20];
//        sprintf(data_name, "%d%s",i, ".txt");
//        ff[i].open(data_name, ios::out);
//        ff[i].close();
//    }




//    runnode a[6] = {runnode(0,0),runnode(5,3),runnode(6,2),runnode(3,2),runnode(12,1)};
//    LoserTree<runnode> l(4,a);
//    l.initial();
//    l.replay(2,runnode(1,1));
//    cout<<l.Winner();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值