poj 3481 Double Queue(平衡二叉树基础练习题)

题意:
。。。
思路:
这道题用来作SBT的练习了。。。

// SBT节点,固定域 l, r, sz
// 需要一个key来比较大小
struct node {
    int l, r, sz, val, K;
    node (int x=0, int y=0):l(0), r(0), sz(0), val(x), K(y){}
};

struct SBT {
    node a[Maxn+5]; // a[0] 是空节点,与所有外部节点相连
    int root, tot;

    void init() {root = tot = 0;}

    inline void rot_R(int &x) { // 右旋
        int k = a[x].l;
        a[x].l = a[k].r;
        a[k].r = x;
        a[k].sz += a[x].sz;
        a[x].sz = a[a[x].l].sz + a[a[x].r].sz + 1;
        x = k;
    }

    inline void rot_L(int &x) { // 左旋
        int k = a[x].r;
        a[x].r = a[k].l;
        a[k].l = x;
        a[k].sz += a[x].sz;
        a[x].sz = a[a[x].l].sz + a[a[x].r].sz + 1;
        x = k;
    }

    void maintain(int &x, int flag) {
        int L = a[x].l, R = a[x].r;
        if (!flag) { // 左子树和右子树的子树比较
            if (a[a[L].l].sz > a[R].sz) {
                rot_R(x);
            }
            else if (a[a[L].r].sz > a[R].sz) {
                rot_L(a[x].l);
                rot_R(x);
            }
            else return;
        }
        else { // 右子树和左子树的子树比较
            if (a[a[R].r].sz > a[L].sz) {
                rot_L(x);
            }
            else if (a[a[R].l].sz > a[L].sz) {
                rot_R(a[x].r);
                rot_L(x);
            }
            else return;
        }

        maintain(a[x].l, 0);
        maintain(a[x].r, 1);
        maintain(x, 0);
        maintain(x, 1);
    }

    node remove(int &x, int key) { // 用前驱覆盖
        node del;
        --a[x].sz;
        if (key == a[x].val || (key < a[x].val && !a[x].l) || (key > a[x].val && !a[x].r)) {
            del = a[x];
            if (!a[x].l || !a[x].r) // 如果是外部节点,直接用子节点覆盖
                x = a[x].l + a[x].r;
            else { // 否则使用前驱覆盖
                node tmp = remove(a[x].l, a[x].val + 1);
                a[x].val = tmp.val;a[x].K = tmp.K;
            }
        }
        else if (key < a[x].val)
            del = remove(a[x].l, key);
        else
            del = remove(a[x].r, key);
        return del;
    }

    void insert(int &x, int val, int K) {
        if (x == 0) {
            x = ++tot;
            a[x] = node(val, K);
            a[x].sz = 1;
            return;
        }
        ++a[x].sz;
        if (val < a[x].val) {
            insert(a[x].l, val, K);
        }
        else {
            insert(a[x].r, val, K);
        }
        maintain(x, val >= a[x].val);
        //cout << "after maintain mid: ";sbt_mid_order(x);cout << endl;
        //cout << "after maintain pre: ";sbt_pre_order(x);cout << endl;
    }

    node front() {
        int i;
        for (i=root;a[i].l;i=a[i].l);
        return a[i];
    }

    node back() {
        int i;
        for (i=root;a[i].r;i=a[i].r);
        return a[i];
    }

    void sbt_mid_order(int x) {
        if (!x) return;
        sbt_mid_order(a[x].l);
        cout << a[x].val << ' ';
        sbt_mid_order(a[x].r);
    }

    void sbt_pre_order(int x) {
        if (!x) return;
        cout << a[x].val << ' ';
        sbt_pre_order(a[x].l);
        sbt_pre_order(a[x].r);
    }
};

SBT sbt;
int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.in", "r", stdin);
#endif
    SPEED_UP
    sbt.init();
    int code, k, p;
    while (cin >> code && code) {
        if (code == 1) {
            cin >> k >> p;
           // cout << "\ninsert: " << p << endl;
            sbt.insert(sbt.root, p, k);
        }
        else if (code == 2) {
            node tmp = sbt.back();
            if (tmp.K)
                sbt.remove(sbt.root, tmp.val);
            cout << tmp.K << endl;
        }
        else if (code == 3) {
            node tmp = sbt.front();
            if (tmp.K)
                sbt.remove(sbt.root, tmp.val);
            cout << tmp.K << endl;
        }
        //cout << "mid: ";sbt.sbt_mid_order(sbt.root);cout << endl;
        //cout << "pre: ";sbt.sbt_pre_order(sbt.root);cout << endl;
        //cout << "size: " << sbt.a[sbt.root].sz << endl;
    }

    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
做一门精致,全面详细的 java数据结构与算法!!!让天下没有难学的数据结构,让天下没有难学的算法,不吹不黑,我们的讲师及其敬业,可以看到课程视频,课件,代码的录制撰写,都是在深夜,如此用心,其心可鉴,他不掉头发,谁掉头发???总之你知道的,不知道的,我们都讲,并且持续更新,走过路过,不要错过,不敢说是史上最全的课程,怕违反广告法,总而言之,言而总之,这门课你值得拥有,好吃不贵,对于你知识的渴求,我们管够管饱话不多说,牛不多吹,我们要讲的本门课程内容:稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值