首页 > 代码库 > 数据结构基础(19) --红黑树的设计与实现(2)

数据结构基础(19) --红黑树的设计与实现(2)

双旋转

单旋转有时会出现一个问题(如下图所示):

技术分享

(如果内侧子孙节点[k1]过深, 则将其单向移动是不会解决问题的)

 

于是就有了双旋转

向右双旋转:

技术分享

    1.首先以k1为轴, k1与k2向左旋转;

    2.然后以k3为轴, k3与旋转之后的k1向右旋转;

//实现
//向右双旋转
template <typename Type>
void RedBlackTree<Type>::doubleRotateWithLeftChild(Node *& k3) const
{
    //首先将其左儿子(k1)向左单旋转
    rotateWithRightChild(k3->left);

    //然后将自己(k3)向右单旋转
    rotateWithLeftChild(k3);
}

向左双旋转:

技术分享

    1.首先以k3为轴, k2k3向右旋转;

    2.然后以k1为轴, k1与旋转之后的k2向左旋转;

//实现
//向左双旋转
template <typename Type>
void RedBlackTree<Type>::doubleRotateWithRightChild(Node *& k1) const
{
    //首先将其右儿子(k2)向右单旋转
    rotateWithLeftChild(k1->right);

    //然后将自己(k1)向左单旋转
    rotateWithRightChild(k1);
}
//注:其实红黑树中并没有用到双旋转, 而是自己实现了一个rotate操作, 
//在此只为了学习双旋转的理论;

测试(在完成双旋转之后):

技术分享

(构造一颗二叉查找树树如图所示, 左边为尚未旋转之前, 右为旋转之后, 以8为轴进行双旋转)

int main()
{
    //用NEG_INF来代表负无穷大
    const int NEG_INF = -999999;
    RedBlackTree<int> tree(NEG_INF);

//双旋转时的测试数据
    tree.insert(12);
    tree.insert(16);
    tree.insert(8);
    tree.insert(10);
    tree.insert(4);
    tree.insert(14);
    tree.insert(2);
    tree.insert(6);
    tree.insert(5);
    cout << tree.header->right->element << endl;    //12
    cout << tree.header->right->left->element << endl;  //8
    cout << tree.header->right->right->element << endl; //16

    cout << tree.header->right->left->left->element << endl;    //4
    cout << tree.header->right->left->right->element << endl;   //10
    cout << tree.header->right->right->left->element << endl;   //14
//  cout << tree.header->right->left->right->left->element << endl;   //5曾经做过哨兵
//  cout << tree.header->right->left->right->right->element << endl;  //5

    cout << tree.header->right->left->left->left->element << endl;  //2
    cout << tree.header->right->left->left->right->element << endl; //6

    cout << tree.header->right->left->left->right->left->element << endl;   //5


    cout << "\n向右双旋转" << endl;
    //以8为基准向右双旋转
    tree.doubleRotateWithLeftChild(tree.header->right->left);
    cout << tree.header->right->element << endl;    //12
    cout << tree.header->right->left->element << endl;  //6
    cout << tree.header->right->right->element << endl; //16

    cout << tree.header->right->left->left->element << endl;    //4
    cout << tree.header->right->left->right->element << endl;   //8
    cout << tree.header->right->right->left->element << endl; //14

    cout << tree.header->right->left->left->left->element << endl;  //2
    cout << tree.header->right->left->left->right->element << endl;  //5
    cout << tree.header->right->left->right->right->element << endl;    //10

    return 0;
}

异常

//在红黑树实现过程中用到的异常构造:
class DSException
{
public:
    DSException(const string &_message = string())
        : message(_message) {}
    ~DSException() {}

    virtual string what() const
    {
        return message;
    }
    virtual string toString() const
    {
        return "Exception: " + what();
    }

private:
    std::string message;

};

class DuplicateItemException : public DSException
{
public:
    DuplicateItemException(const string &_msg = string())
        : DSException(_msg) {}
};


数据结构基础(19) --红黑树的设计与实现(2)