zoukankan      html  css  js  c++  java
  • BST

    #include<bits/stdc++.h>
    using namespace std;
    
    struct RBTreeNode {
        bool black;
        int val;
        RBTreeNode *left,*right,*parent;
        RBTreeNode(int v = 0) {
            val = v;
            black = false;
            left = right = parent = NULL;
        }
    };
    struct RBTree {
    private:
        RBTreeNode *root;
    
        void leftRoate(RBTreeNode*node) {
            RBTreeNode*tmp = node->left;//tmp可能为NULL
            RBTreeNode*parent = node->parent;
            RBTreeNode*grandpa = parent->parent;
    
            node->left = parent;
            parent->right = tmp;
    
            if(tmp) tmp->parent = parent;
            parent->parent = node;
            node->parent = grandpa;
            if(!grandpa) { 
                root = node;
                return;
            }
            if(grandpa->left == parent) grandpa->left = node;
            else grandpa->right = node;
        }
        void rightRoate(RBTreeNode*node) { //《不要随便传引用!!!》-- RBTreeNode*&node 在旋转时传入node->parent->left
            RBTreeNode*tmp = node->right;         //然后第六行赋值parent->left = tmp(tmp == node) 直接导致node<-NULL,段错误找了好久
            RBTreeNode*parent = node->parent;
            RBTreeNode*grandpa = parent->parent;
    
            node->right= parent;
            parent->left= tmp;
    
            if(tmp) tmp->parent = parent;//tmp可能为NULL,这里段错误找了好久
            parent->parent = node;
            node->parent = grandpa;
            if(!grandpa) {     //如果改变了根要把树的根给改变了,不然会出现只剩一个根的情况*********这里出错找了好久
                root = node;
                return;
            }
            if(grandpa->left == parent) grandpa->left = node;
            else grandpa->right = node;
        }
    
        void insertAdjust(RBTreeNode *root) {
            if(!root->parent) { //当前插入节点为根,变为黑
                root->black = true;
                return;
            }
            RBTreeNode* parent = root->parent;
            if(parent->black) {    //红连黑,什么都不用做
                return;
            }
            RBTreeNode* &grandpa = parent->parent;    //父节点为红,必不为根
            //assert(grandpa && grandpa->black);
            if(grandpa->left && grandpa->right && !grandpa->left->black && !grandpa->right->black) { 
                //祖父节点为黑,其两个儿子节点为红,祖父节点变红,儿子节点变黑,往上调整
                grandpa->black = false;
                grandpa->left->black = grandpa->right->black = true;
                insertAdjust(grandpa);
                return;
            }
            if(grandpa->right == parent){
                if(parent->left == root) {
                    rightRoate(root);
                } else {
                    root = root->parent;
                }
                leftRoate(root);
                swap(root->black,root->left->black);
                return;
            }
            if(grandpa->left == parent) {
                if(parent->right == root) {
                    leftRoate(root);
                } else {
                    root = root->parent;
                }
                rightRoate(root);
                swap(root->black,root->right->black);
                return;
            }
            //assert(0);
        }
    
        void insert(RBTreeNode *parent,RBTreeNode *&root,int val) {
            if(!root) {
                root = new RBTreeNode(val);
                root->parent = parent;
                insertAdjust(root);
                return;
            }
            //printf("root:%p left:%p right:%p parent:%p val:%d black:%d
    ",root,root->left,root->right,root->parent,root->val,root->black);
            if(val > root->val) {
                insert(root,root->right,val);
            }
            else {
                insert(root,root->left,val);
            }
        }
    
        RBTreeNode* begin(RBTreeNode *root) {
            while(root && root->left) root = root->left;
            return root;
        }
    
        RBTreeNode* next(RBTreeNode *root) {
            if(root->right) {
                root = root->right;
                while(root->left) root = root->left;
                return root;
            }
            while(root->parent && root->parent->right == root) root = root->parent;
            return root->parent;
        }
    
        int check(RBTreeNode *root) {
            if(!root) return 0;
            if(root->left) {
                assert(!(!root->black && !root->left->black));
                assert(root->left->parent == root);
                assert(root->left->val <= root->val);
            }
            if(root->right) {
                assert(root->right->parent == root);
                assert(root->right->val >= root->val);
            }
            int a = check(root->left);
            int b = check(root->right);
            assert(a == b);
            return a + root->black;
        }
    
        bool erase(RBTreeNode *&root,RBTreeNode *node) {
            if(!node) return false;
            if(node->left && node->right) { //两个子节点,拿左儿子的最右儿子或右儿子的最左儿子复制到要删除的节点
                RBTreeNode *tmp = node->left;
                while(tmp->right) tmp = tmp->right;//取左儿子的最右儿子
                node->val = tmp->val; //copy
                node = tmp;
            }
            if(!node->black) { //被删除节点为红->这个节点不可能为根,直接删除即可
                RBTreeNode*child = node->left;
                RBTreeNode*parent = node->parent;
                if(child) child->parent = parent;
                assert(parent);
                if(parent->left == node) parent->left = child;
                else parent->right = child;
                delete node;
                return true;
            }
            RBTreeNode *child=NULL;
            if(node->left) {
                child = node->left;
            } else if(node->right) {
                child = node->right;
            }
            RBTreeNode *parent = node->parent;
            if(child) child->parent = parent;
    
            if(!parent) root = child;
            else if(parent->left == node) parent->left = child;
            else parent->right = child;
            eraseAdjust(child,parent);
            delete node;
            return true;
        }
    
        void eraseAdjust(RBTreeNode *node,RBTreeNode *parent) {
            if(!parent) {    
                //1.1 子节点为根,染为黑
                if(node) node->black = true;
                return;
            }
            if(node && !node->black) { 
                //1.2子节点为红,直接染为黑
                node->black = true;
                return;
            }
    
            RBTreeNode *brother = (parent->left == node ? parent->right : parent->left);
            if(!parent->black) {    //2.父节点为红,兄弟节点必为黑
                assert((!brother||brother->black));
                if((!brother->left || brother->left->black) && (!brother->right || brother->right->black)) {
                    //2.1 兄弟节点两个儿子为 black,black
                    swap(brother->black,parent->black);
                    return;
                }
                if(parent->left == node) {
                    if(brother && brother->left && !brother->left->black) {    
                        //2.2 兄弟节点两个儿子为 red,?
                        parent->black = true;
                        rightRoate(brother->left);
                        leftRoate(parent->right);
                        return;
                    }
                    //2.3 兄弟节点两个儿子为 black,red
                    leftRoate(brother);
                    return;
                } else {
                    if(brother && brother->right && !brother->right->black) {    
                        //2.2 兄弟节点两个儿子为 ?,red
                        parent->black = true;
                        leftRoate(brother->right);
                        rightRoate(parent->left);
                        return;
                    }
                    //2.3 兄弟节点两个儿子为 red,black
                    rightRoate(brother);
                    return;
                }
            }
            //3.父节点为黑
            if(brother && !brother->black) { 
                //3.1 兄弟节点为红,两个儿子节点必为黑
                swap(parent->black,brother->black);
                if(parent->left == node) leftRoate(brother);
                else rightRoate(brother);
                eraseAdjust(node,parent);    //处理后node路径上还是少一个黑色节点,重新调整
                return;
            }
    
            //3.2 兄弟节点为黑
            assert(brother);    //brother必不为nil,否则两边黑节点个数不一样
            if((!brother->left||brother->left->black) && (!brother->right||brother->right->black)) {
                //3.2.1 两个儿子节点为黑
                brother->black = false;
                eraseAdjust(parent,parent->parent);
                return;
            }
            if(parent->left == node) {
                if(brother->left && !brother->left->black) { 
                    //3.2.2 兄弟节点左儿子为红
                    brother->left->black = true;
                    rightRoate(brother->left);
                    leftRoate(parent->right);
                    return;
                }
                //3.2.3 兄弟节点儿子为 black,red
                brother->right->black = true;
                leftRoate(brother);
                return;
            } else {
                if(brother->right && !brother->right->black) { 
                    //3.2.2 兄弟节点左儿子为红
                    brother->right->black = true;
                    leftRoate(brother->right);
                    rightRoate(parent->left);
                    return;
                }
                //3.2.3 兄弟节点儿子为 black,red
                brother->left->black = true;
                rightRoate(brother);
                return;
            }
        }
    
        RBTreeNode* find(RBTreeNode *root,int val) {
            while(root && root->val != val) {
                if(root->val > val) root = root->left;
                else root = root->right;
            }
            return root;
        }
    public:
        RBTree() { root = NULL; }
        void insert(int x) {
            insert(NULL,root,x);
        }
        void print() {
            for(RBTreeNode *it = begin(root);it;) {
                printf("%d",it->val);
                it = next(it);
                if(!it) printf("
    ");
                else printf(" ");
            }
            /*for(RBTreeNode *it = begin(root);it;it=next(it)) {
                printf("self:%p parent:%p left:%p right:%p val:%d black:%d
    ",it,it->parent,it->left,it->right,it->val,it->black);
            }*/
        }
        RBTreeNode* begin() {
            return begin(root);
        }
        RBTreeNode* next() {
            return next(root);
        }
        int check() {
            check(root);
        }
        RBTreeNode* find(int val) {
            return find(root,val);
        }
        bool erase(RBTreeNode *node) {
            return erase(root,node);
        }
    };
    
    
    int main() {
        int n;
        while(scanf("%d",&n)==1) {
            RBTree a;
            vector<int>arr;
            for(int i=0,x;i<n;i++) {
                //scanf("%d",&x);
                x = rand();
                arr.push_back(x);
                a.insert(x);
                a.check();
            }
            a.print();
            printf("--------------------------
    ");
            for(int i=0,x;i<n;i++) {
                //scanf("%d",&x);
                RBTreeNode *tmp = a.find(arr[i]);
                printf("erase:%d
    ",arr[i]);
                a.erase(tmp);
                //a.print();
                a.check();
            }
            break;
        }
        return 0;
    }

     详细讲解:

    红黑树 - wiki

  • 相关阅读:
    卷积神经网络与典型结构
    机器学习之信息熵
    机器学习读书笔记第三章(1):线性模型
    神经网络之:S型神经元
    mysql只保留一条有效数据,删除其他重复的数据
    mysql索引
    mysql自定义函数收集
    MySql中循环的使用
    WCF的例子
    C盘满了如何清理
  • 原文地址:https://www.cnblogs.com/cdyboke/p/7822483.html
Copyright © 2011-2022 走看看