败者树 K路归并


#include <iostream>
#include <vector>

using namespace std;
//交换两个数
void swap(int *a,int *b)
{
    int temp=*a;
    *a=*b;
    *b=temp;
}

const int branchesLength = 20;

int branches[branchesLength][500] = {
    {1000,900},{999,888},{1001,990},{887,877},{987,978},
    {1001,901},{992,883},{1005,992},{887,877},{987,978},
    {1002,902},{993,884},{1007,991},{887,877},{987,978},
    {1003,903},{994,992},{989,900},{887,877},{987,978}
};

//const int branchesLength = 5;
//
//int branches[branchesLength][500] = {
//    {10},{9},{20},{6},{12}
//};

//非叶子节点
int tree[branchesLength];
//叶子节点
int nodes[branchesLength];
//第i路当前第几个元素
int nodes_interator[branchesLength] = {0};

void printTree()
{
    cout<<"tree is :";
    for(int i = 0;i<branchesLength;i++)
        cout<<tree[i]<<" ";
    cout<<endl;
}
void put(int index)
{
    nodes[index] = branches[index][nodes_interator[index]++];
}

int get(int index)
{
    return nodes[index];
}

void adjust(int index)
{
    int size = branchesLength;
    int t = (size + index) / 2;
    int temp = index;//tree[t];
    while(t > 0)
    {
        
        cout<<"Adjust i= "<<index<<" t= "<<t<<" small = "<<temp<<endl;
        cout<<"index compare "<<tree[t]<<" and "<<temp<<endl;
        cout<<"compare "<<nodes[tree[t]]<<" and "<<nodes[temp]<<endl;
        if(get(tree[t]) < get(temp))
        {
//            temp = tree[t];
//            tree[t] = index;
//            index = temp;
            
            swap(&tree[t],&temp);
        }
        t /= 2;
        printTree();
    }
    tree[0] = temp;
}

vector<int> merge()
{
    //依次读入数据进行归并排序,并返回排序后的列表
    vector<int> list; //排序后的列表
    int top;
    int i = 0;
    while(i < 10)
    {
        top = tree[0];
        cout<<"getTop "<<top<<endl;
        list.push_back(get(top));
        i++;
        put(tree[0]);
        adjust(tree[0]);
    }

    vector<int>::iterator it = list.begin();
    for(;it != list.end();it++)
    {
        cout<<*it<<" - ";
    }
    cout<<endl;
    return list;
}

void init()
{
    int size = branchesLength;
    for(int i = 0; i < size;i++)
    {
        put(i);
    }
    int winner = branchesLength;
//    for(int i = 1;i < size;i++)
//    {
//        if(get(i) > get(winner))
//        {//叶子节点
//            winner = i;
//        }
//    }
    
    for(int i = 0;i < branchesLength;i++)
    {
        tree[i] = branchesLength;
    }
    for(int i = size - 1;i >= 0;i--)
    {
        adjust(i);
        printTree();
    }
}

int main()
{
    init();
    merge();
}
#include <iostream>
using namespace std;

const int MINKEY = 0;//假设给定数组中所有数都大于0
const int MAXKEY = 200;//假设给定数组中所有数都小于200

//完全二叉树的叶子节点个数比度为2的节点个数多1
void Adjust(int &k, int* &ls, int* &b, int i)
{
    //控制ls[]的下标
    int t = (i + k) / 2;//第一个非叶子结点的下标、第二个。。。
    //控制b[]的下标
    int small = i;
    for (; t > 0; t /= 2){
//        cout<<"Adjust i= "<<i<<" t= "<<t<<" small = "<<small<<endl;
//        cout<<"index compare "<<ls[t]<<" and "<<small<<endl;
//        cout<<"compare "<<b[ls[t]]<<" and "<<b[small]<<endl;
        if (b[ls[t]]<b[small]){
            swap(small, ls[t]);
//            cout<< "ls["<<t<<"] = "<<ls[t]<<endl;
        }
//        else{
//            small = small;
//        }
//        cout<<"tree is :";
//        for (int i = 0; i < k; ++i)
//            cout << ls[i] << " ";
//        cout<<endl;
    }
    ls[0] = small;
}
void createLoserTree(int* arr[],int &k, int* &ls, int* &b)
{
    //init b[]
    for (int i = 0; i < k; ++i)
        b[i] = arr[i][0];
    b[k] = MINKEY;
    //init ls[]
    for (int i = 0; i < k; ++i)
        ls[i] = k;//最小值(绝对的胜者)的序号
    //有k个叶子节点
    //从最后一个叶子节点开始,沿着从叶子节点到根节点的路径调整
    for (int i = k - 1; i >= 0; --i){
        Adjust(k, ls, b, i);
//        cout <<"ls :";
//        for (int i = 0; i < k; ++i)
//            cout << ls[i] << " ";
//        cout << endl;
    }
}

void kMerge(int* arr[], int* arrayElementsCount, int& k, int* &ls, int* &b, int& mostMinCount)
{
    int* index = new int[k];
    for (int i = 0; i < k; ++i)
        index[i] = 0;
    for (int i = 0; i < mostMinCount; ++i){
        int s = ls[0];
        cout << b[s] << " ";
        ++index[s];
        if (index[s] < arrayElementsCount[s])
            arr[s][0] = arr[s][index[s]];
        else
            arr[s][0] = MAXKEY;
        b[s] = arr[s][0];
        Adjust(k, ls, b, s);
    }
    cout << endl;
    delete[] index;
}

int main()
{
    int arr0[] = {10};//, 6, 15, 25 };
    int arr1[] = {9};//, 12, 37, 48, 50 };
    int arr2[] = {20};//, 10, 15, 16 };
    int arr3[] = {6};//, 9, 18, 20 };
    int arr4[] = {12};//, 10, 11, 40 };
//    int arr5[] = {5};//, 6, 15, 25 };
//    int arr6[] = {7};//, 12, 37, 48, 50 };
//    int arr7[] = {3};//, 10, 15, 16 };

    //6,9,10,10,11,12,15,15,16,18,20,25,37,40,48,50
    int* arr[] = { arr0, arr1, arr2, arr3, arr4/*,arr5,arr6,arr7 */};

    int k = sizeof(arr) / sizeof(arr[0]);
    int* arrayElementsCount = new int[k];
//    for(int i = 0;i < k;i++)
//    {
//        arrayElementsCount[i] = sizeof(arr[i]) / sizeof(int);
//    }

    arrayElementsCount[0] = sizeof(arr0) / sizeof(arr0[0]);
    arrayElementsCount[1] = sizeof(arr1) / sizeof(arr1[0]);
    arrayElementsCount[2] = sizeof(arr2) / sizeof(arr2[0]);
    arrayElementsCount[3] = sizeof(arr3) / sizeof(arr3[0]);
    arrayElementsCount[4] = sizeof(arr4) / sizeof(arr4[0]);
//    arrayElementsCount[5] = sizeof(arr5) / sizeof(arr5[0]);
//    arrayElementsCount[6] = sizeof(arr6) / sizeof(arr6[0]);
//    arrayElementsCount[7] = sizeof(arr7) / sizeof(arr7[0]);
    //记录每个数组的首元素
    int* b = new int[k + 1];
    //记录败者的下标
    int* ls = new int[k];
    createLoserTree(arr, k,ls,b);
    int mostMinCount = 5;
    kMerge(arr, arrayElementsCount, k, ls, b, mostMinCount);
    delete[] b;
    delete[] ls;
    delete[] arrayElementsCount;

    //system("pause");
}
#include <iostream>
#include <vector>

using namespace std;

//共有20路数组
const int branchesLength = 20;
int branches[branchesLength][500] = 
{
{1000, 900},{999, 888},{1001,990},{887, 877}, {987,978},
{1001, 901},{992, 883},{1005, 992},{887, 877},{987,978},
{1002, 902},{993, 884},{1007,991},{887, 877},{987, 978},
{1003, 903},{994, 882},{989, 900},{887, 877},{987, 978}
};


//const int branchesLength = 5;
//
//int branches[branchesLength][500] = {
//    {10},{9},{20},{6},{12}
//
//};
//非叶子节点
int tree[branchesLength];
//叶子节点
int nodes[branchesLength];
int nodes_iterator[branchesLength] = {0};

void printTree()
{
    cout<<"tree is :";
    for(int i = 0;i<branchesLength;i++)
        cout<<tree[i]<<" ";
    cout<<endl;
}

void put(int index) 
{
    nodes[index] = branches[index][nodes_iterator[index]++];
}
int get(int index){
    return nodes[index];
}
void adjust(int index) {
    int size = branchesLength;
    int t = (branchesLength + index) / 2;
    int temp = index;
    while(t > 0)
    {
        if(get(tree[t]) < get(temp))
        {
        temp = tree[t];
        tree[t] = index;
        index = temp;
        }
        t /= 2;
    }
    
    tree[0] = temp;
    printTree();
}

vector<int> merge() 
{ //依次读取数据源的数据进行归并排序,返回排序后的数据列表
    vector<int> list1; //记录排好序的数据
    int top;
    int i = 0;
    while( i< 10) //仅输出10个数据供测试
    {
        top = tree[0];
        list1.push_back(get(top));
        //list1.push_back(branches[tree[0]][nodes[tree[0]]);
        i++;
        put(tree[0]);
        adjust(tree[0]);
    }
    return list1;
}
//初始化构建败者树
void init(){
    int size = branchesLength;
    for(int i = 0; i < size; i++)
    {
        put(i);
    }
    
    for (int i = 0; i < branchesLength; i++) //非叶子结点初始化为冠军结点
    {
        tree[i] = 2;//branchesLength;
    }

    for (int i = size - 1; i >= 0; i--) //从后向前依次调整非叶子结点
    {
        adjust(i);
    }

}

int main()
{
    init();
    vector<int> result = merge();
    for (vector<int>::iterator it = result.begin(); it != result.end(); it++ )
    {
        cout<<*it<< " ";
    }
    cout<<endl;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值