码迷,mamicode.com
首页 > 其他好文 > 详细

BST总结

时间:2020-02-03 09:27:34      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:大于   treap   ret   一点   return   bst   img   insert   排名   

BST 是 Treap 的基础。

这位大佬写的不错

只写一点基本操作方便自己理解。

性质:左儿子 < 自己 < 右儿子

上图

技术图片

插入

根据性质,比当前结点小就插入左子树,大就插入右子树,相等直接令当前结点的 cnt++ 即可。

void insert(int o, int k) {//在当前结点 o 插入 k 值
    tr[o].sz++;
    if (tr[o].val == k) {
        tr[o].cnt++;
        return;
    }
    if (v < tr[o].val) {
        if (tr[o].ls != 0) insert(tr[o].ls, k);
        else {
            tot++;
            tr[tot].val = k, tr[tot].sz = tr[tot].cnt = 1;
            tr[o].ls = tot;
        }
    }
    else {
        if (tr[o].rs != 0) insert(tr[o].rs, k);
        else {
            tot++;
            tr[tot].val = k, tr[tot].sz = tr[tot].cnt = 1;
            tr[o].rs = tot;
        }
    }

删除

直接找到该数字所在的结点,令 cnt-- 就好了。

代码就不写了

因为上面那位大佬没写

前驱

一个数的前驱是指小于这个数的最大的数。

如果当前结点的值大于这个数,直接递归进左子树中找,小于的话就递归进右子树中找。

int pre(int o, int k, int ans) {
    if (tr[o].val >= k) {
        if (!tr[o].ls) return ans;
        else return pre(tr[o].ls, k, ans);
    }
    else {
        if (!tr[o].rs) {
            if (tr[o].val < k) return tr[o].val;//必须小于这个数
            else return ans;
        }
        else if (tr[o].cnt) return pre(tr[o].rs, k, tr[o].val);//注意此时当前结点的值一定小于 ans ,要更新 ans
        else return pre(tr[o].rs, k, ans);
    }
}

后继

和前驱的方法是一样的。

int suf(int o, int k, int ans) {
    if (tr[o].val <= k) {
        if (!tr[o].rs) return ans;
        else return suf(tr[o].rs, k, ans);
    }
    else {
        if (!tr[o].ls) {
            if (tr[o].val > k) return tr[o].val;
            else return ans;
        }
        else if (tr[o].cnt) return suf(tr[o].ls, k, tr[o].val);
        else return suf(tr[o].ls, k, ans);
    }
}

排名

当前结点的排名为它的左子树大小加上自己的 cnt ,如果小于要找的排名,就递归进右子树,并更新排名,否则先查找是否是当前结点,不是再去左子树。

int GetRank(int o, int rk) {
    if (!o) return INF;
    if (tr[tr[o].ls].sz >= rk) return GetRank(tr[o].ls, rk);
    else if (tr[tr[o].ls].sz + tr[o].cnt >= rk) return tr[o].val;
    return GetRank(tr[o].rs, rk - tr[tr[o].ls].sz - tr[o].cnt);
}

找值

如果当前结点的值小于查询的值,就在右子树找,同时排名要加上当前结点左子树的大小和当前结点的 cnt 值,否则直接递归进左子树找。

int GetVal(int o, int k) {
    if (!o) return 0;
    if (tr[o].val == k) return tr[tr[o].ls].sz + 1;
    else if (tr[o].val > k) return GetVal(tr[o].ls, k);
    return GetVal(tr[o].rs, k) + tr[tr[o].ls].sz + tr[o].cnt;
}

BST总结

标签:大于   treap   ret   一点   return   bst   img   insert   排名   

原文地址:https://www.cnblogs.com/hlw1/p/12254474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!