开始造轮子-红黑树的实现

来源:互联网 发布:公务员网络培训系统 编辑:程序博客网 时间:2024/05/19 13:18

概念

红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结
点的颜色,可以是red或者black,通过对任何一条从根节点到叶子结点上
的简单路径来约束,红黑树保证最长路径不超过最短路径的两倍,因而近视
平衡。

性质

  1. 每个结点不是红色就是黑色
  2. 根节点是黑色的
  3. 如果一个根节点是红色的,则它的两个叶子结点是黑色的(没有两个连续
    的红色结点)
  4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相
    同数目的黑色结
    这里写图片描述
    这里写图片描述
#include<stdio.h>//实现红黑树的插入、检测功能enum COLOR{    RED,    BLACK,};template<class K, class V>struct RBTreeNode{    RBTreeNode(K key, V val)    :_pLeft(NULL)    , _pRight(NULL)    , _pParent(NULL)    , _key(key)    , _val(val)    , _col(RED)    {    }    RBTreeNode<K, V>* _pLeft;    RBTreeNode<K, V>* _pRight;    RBTreeNode<K, V>* _pParent;    K _key;    V _val;    COLOR _col;};template<class K, class V>class RBTree{public:    typedef RBTreeNode<K, V> Node;    RBTree()        :_pRoot(NULL)    {    }    RBTree(K key, V val)    {        //疑问1:问什么要调用拷贝函数        _pRoot = new Node(key, val);        _pRoot->_col = BLACK;    }    //拷贝构造    RBTree(const RBTree<K, V>& tree)    {        _Copy(tree._pRoot, _pRoot);    }    //赋值的三种写法:普通版  交换版   利用临时变量,函数结束自动销毁    ////赋值第二种写法    //RBTree<K, V>& opeartor = (const RBTree<K, V>& tree)//返回引用    //{    //  if (this != &tree)//为什么要判断:1.避免无效拷贝    //  {    //      RBTree<K, V> tmp(tree);    //      swap(_root,tree->_root);    //  }    //  return *this;    //}    //赋值第三种写法    RBTree<K, V>& opeartor = (const RBTree<K, V> tree)//返回引用    {        if (this != &tree)//为什么要判断:1.避免无效拷贝        {            swap(_root, tree->_root);        }        return *this;    }    bool Find(const K &key)    {        Node*cur = _pRoot;        while (cur)        {            if (cur->_key == key)            {                return true;            }            else if (cur->_key < key)            {                cur = cur->_pRight;            }            else            {                cur = cur->_pLeft;            }        }        return false;    }    //红黑树的插入操作    bool Insert(const K&key, const V &val)    {        if (_pRoot == NULL)        {            _pRoot = new Node(key, val);            _pRoot->_col = BLACK;            return true;        }        //先找到对应位置        Node* cur = _pRoot;        Node*parent = NULL;        while (cur)        {            if (cur->_key == key)            {                return false;            }            else if (cur->_key < key)            {                parent = cur;                cur = cur->_pRight;            }            else            {                parent = cur;                cur = cur->_pLeft;            }        }        cur = new Node(key, val);        if (parent->_key < key)        {            parent->_pRight = cur;        }        else        {            parent->_pLeft = cur;        }        cur->_pParent = parent;        //根据情况进行调整树        //思路:最重要的的四个节点:cur parent  g  u        //分情况进行解决        //【情况一】cur为红,p为红,g为黑,u存在且为红          //则将p, u改为黑,g改为红,然后把g当成cur,继续向上调整。        while (cur != _pRoot&&parent->_color == RED)        {            Node* grand = parent->_pParent;            if (parent == grand->_pLeft)            {                Node* uncle = grand->_pRight;                if (uncle&&uncle->_col == RED)//叔叔结点颜色是红色                {                    grand->_col = RED;                    parent->_col = BLACK;                    uncle->_col = BLACK;                    cur = grand;                    parent = parent->_pParent;//红色结点上移,需要继续判断                }                else  //叔叔结点不存在或者为黑色节点                {                    if (cur == parent->_pRight)                    {                        Rotate(parent);//先对parent进行左旋                        parent = cur;                    }                    RotateR(grand);//对祖父节点进行右旋                    parent->_col = BLACK;                    grand->_col = RED;                    break;                }            }            else            {                //如果cur是parent的左孩子,则需要进行先右旋将其变为左左的情况                if (cur == parent->_pLeft)                {                    RotateR(parent);                    parent = cur;                }                RotateL(grand);                parent->_col = BLACK;                grand->_col = RED;                break;            }        }        _pRoot->_col = BLACK;        return true;    }    bool IsBalance()    {        if (_pRoot == NULL)        {            return true;        }        if (_pRoot->_col == RED)        {            return false;        }        int count = 0;        Node* cur = _pRoot;        while (cur)        {            if (cur->_col == BLACK)            {                count++;            }            cur = cur->_pLeft;        }        int num = 0;        return IsBalance(_pRoot, num, count);    }    ~RBTree()    {        _Detroy(_pRoot);    }private:    void _Copy(Node* root, Node* & newroot)    {        if (root == NULL)        {            return;        }        Node*cur = new Node(root->_key, root->_val);        cur->_col = root->_col;        newroot = cur;        cur->_pParent = newroot->_pParent;        _Copy(root->_pLeft, cur->_pLeft);        _Copy(root->_pRight, cur->_pRight);    }    bool IsBalance(Node* root, int num, int&count)    {        if (root == NULL)        {            return num == count;        }        if (root->_col == RED&&root->_pParent->_col == RED)        {            return false;        }        if (root->_col == BLACK)        {            num++;        }        return _IsBalance(root->_pLeft, num, count) && _IsBalance(root->_pRight, num, count);    }    //左旋    void RotateL(Node* parent)    {        Node* ppNode = parent->_pParent;        Node* subR = parent->_pRight;        parent->_pRight = subR->_pLeft;        if (subR->_pLeft)        {            subR->_pLeft->_pParent = parent;        }        if (ppNode == NULL)        {            _pRoot = subR;            _pRoot->_pParent = NULL;        }        else        {            if (ppNode->_pLeft == parent)            {                ppNode->_pLeft = subR;            }            else            {                ppNode->_pRight = subR;            }            subR->_pParent = ppNode;        }    }    //右旋    void RotateR(Node* parent)    {        Node* ppNode = parent->_pParent;        Node* subL = parent->_pLeft;        parent->_pLeft = subL->_pRight;        if (subL->_pRight)        {            subL->_pRight->_pParent = parent;        }        subL->._pRight = parent;        parent->_pParent = subL;        if (ppNode == NULL)        {            _pRoot = subL;            _pRoot->_pParent = NULL;        }        else        {            if (ppNode->_pLeft == parent)            {                ppNode->_pLeft = subL;            }            else            {                ppNode->_pRight = subL;            }            subL->_pParent = ppNode;        }    }    //RBtree的销毁  后序销毁    void _Destroy(Node*& root)    {        if (root)        {            _Destroy(root->_pLeft);            _Destroy(root->_pRight);            //销毁结点            delete root;            root = NULL;        }    }private:    Node* _pRoot;};
原创粉丝点击