zoukankan      html  css  js  c++  java
  • 败者树

    大文件排序

    #include <stdio.h>
    #define k 5
    #define MAXKEY 10000
    #define MINKEY -1
    typedef int LoserTree[k];//表示非终端结点,由于是完全二叉树,所以可以使用一维数组来表示
    typedef struct {
        int key;
    }ExNode, External[k + 1];
    External b;//表示败者树的叶子结点
    //a0-a4为5个初始归并段
    int a0[] = { 10,15,16 };
    int a1[] = { 9,18,20 };
    int a2[] = { 20,22,40 };
    int a3[] = { 6,15,25 };
    int a4[] = { 12,37,48 };
    //t0-t4用于模拟从初始归并段中读入记录时使用
    int t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;
    //沿从叶子结点b[s]到根结点ls[0]的路径调整败者树
    void Adjust(LoserTree ls, int s) {
        int t = (s + k) / 2;//叶子结点对应根节点下标
        while (t > 0) {
            //判断每一个叶子结点同其双亲结点中记录的败者的值相比较,调整败者的值,其中 s 一直表示的都是胜者
            if (b[s].key > b[ls[t]].key) {//最开始,ls[t]是k,b[k]是MINKEY
                int swap = s;
                s = ls[t];
                ls[t] = swap;
                //ls[t] = s;
            }
            t = t / 2;
        }
        //最终将胜者的值赋给 ls[0]
        ls[0] = s;
    }
    //创建败者树
    void CreateLoserTree(LoserTree ls) {
        b[k].key = MINKEY;
        //设置ls数组中败者的初始值
        for (int i = 0; i < k; i++) {
            ls[i] = k;
        }
        //对于每一个叶子结点,调整败者树中非终端结点中记录败者的值
        for (int i = k - 1; i >= 0; i--) {
            Adjust(ls, i);
        }
    }
    
    //模拟从外存向内存读入初始归并段中的每一小部分
    void input(int i) {
        switch (i) {
        case 0:
            if (t0 < 3) {
                b[i].key = a0[t0];
                t0++;
            }
            else {
                b[i].key = MAXKEY;
            }
            break;
        case 1:
            if (t1 < 3) {
                b[i].key = a1[t1];
                t1++;
            }
            else {
                b[i].key = MAXKEY;
            }
            break;
        case 2:
            if (t2 < 3) {
                b[i].key = a2[t2];
                t2++;
            }
            else {
                b[i].key = MAXKEY;
            }
            break;
        case 3:
            if (t3 < 3) {
                b[i].key = a3[t3];
                t3++;
            }
            else {
                b[i].key = MAXKEY;
            }
            break;
        case 4:
            if (t4 < 3) {
                b[i].key = a4[t4];
                t4++;
            }
            else {
                b[i].key = MAXKEY;
            }
            break;
        default:
            break;
        }
    }
    //败者树的建立及内部归并
    void K_Merge(LoserTree ls) {
        //模拟从外存中的5个初始归并段中向内存调取数据
        for (int i = 0; i <= k; i++) {
            input(i);
        }
        //创建败者树
        CreateLoserTree(ls);
        //最终的胜者存储在 is[0]中,当其值为 MAXKEY时,证明5个临时文件归并结束
        while (b[ls[0]].key != MAXKEY) {
            //输出过程模拟向外存写的操作
            printf("%d ", b[ls[0]].key);
            //继续读入后续的记录
            input(ls[0]);
            //根据新读入的记录的关键字的值,重新调整败者树,找出最终的胜者
            Adjust(ls, ls[0]);
        }
    }
    int main(int argc, const char * argv[]) {
        LoserTree ls;
        K_Merge(ls);
        return 0;
    }
  • 相关阅读:
    Saltstack module gem 详解
    Saltstack module freezer 详解
    Saltstack module firewalld 详解
    Saltstack module file 详解
    Saltstack module event 详解
    Saltstack module etcd 详解
    Saltstack module environ 详解
    Saltstack module drbd 详解
    Saltstack module dnsutil 详解
    获取主页_剥离百度
  • 原文地址:https://www.cnblogs.com/beixiaobei/p/10914216.html
Copyright © 2011-2022 走看看