左旋转右旋转双旋

Posted 一乐乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了左旋转右旋转双旋相关的知识,希望对你有一定的参考价值。

左旋转、右旋转、双旋

 

1,LL :– 右旋转(单旋):为啥LL ,要用右旋转:LL 的意思是:左左,说明左边高度多了一个?

--------------------左边过重失衡,右旋转,把重量匀称一点到右边。

 

2,RR: – 左旋转(单旋):为啥RR ,要用左旋转:RR 的意思是:右右,说明右边高度多了一个?

--------------------右边过重失衡,左旋转,把重量匀称一点到左边。

 

3,LR – RR:左旋转,然后得到 LL,再右旋转(双旋):首先看LR-RR结构的最后一对是RR,

■ 为啥RR, 要用左旋转:RR 的意思是:右右,说明右边高度多了一个?

--------------------右边过重失衡,左旋转,把重量匀称一点到左边。

■ 然后得到LL,要用右旋转,LL的意思是:左左,说明左边高度多了一个?

--------------------左边过重失衡,右旋转,把重量匀称一点到右边。

      

 

4,RL – LL:右旋转,然后得到 RR,再左旋转(双旋):首先看RL-LL 结构最后一对是LL,

■ 为啥LL, 要用右旋转:LL 的意思是:左左,说明左边高度多了一个?

--------------------左边过重失衡,右旋转,把重量匀称一点到右边。

■ 然后得到RR,要用左旋转,RR的意思是:右右,说明右边高度多了一个?

--------------------右边过重失衡,左旋转,把重量匀称一点到左边。

      

 

1、旋转的意义:就是为了匀称掉失衡的状态。

✿ 最后一个字母就是提示失衡的情况:

● LL: 是左边失衡~ 右旋转

● RR:是右边失衡~ 左旋转

● LR-RR: (可以看到该结构最后一对是 RR,是右边失衡)左旋转,处理后得到~LL(是左边失衡),右旋转。

● RL-LL:(可以看到该结构最后一对是 LL,是左边失衡)右旋转,处理后得到~RR(是右边失衡),左旋转。

红黑树实现


概念左旋转右旋转颜色反转插入节点过程设计架构

概念

  • 节点是红色或黑色。

  • 根节点是黑色。

  • 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

  • 每个Nil节点都是黑色

  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

左旋转

左旋转过程:

1            node                               x
2           /   \     左旋转                /  \
3          T1   x   --------->   node   T3
4              / \                         /   \
5             T2 T3                    T1   T2

 1/**
2    Node<Key, Value>* leftRotate(Node<Key, Value> *node)
3    {
4        Node<Key, Value>* x = node->right;
5        node->right = x->left;
6        x->left = node;
7
8        x->color = node->color;
9        node->color = Node::RED;
10        return x;
11    }

右旋转

右旋转过程:

1     node                         x
2    /   \     右旋转         /  \
3   x    T2   ------->   y   node
4  / \                             /  \
5 y  T1                         T1  T2

1    Node<Key, value>* rightRotate(Node<Key, Value>* node)
2    {
3        Node<key, Value> *x = node->left;
4        node->left = x->right;
5        x->right = node;
6
7        x->color = node->color;
8        node->color = Node::RED;
9        retu

颜色反转

 1/*
2     *颜色反转
3     *
4     */

5    void flipColors(Node<Key, Value>* node)
6    {
7        node->color = Node::RED;
8        node->left->color = Node::BLACK;
9        node->right->color = Node::BLACK;
10    }

插入节点过程

每次插入,跟二叉搜索树一样的递归过程,唯一多的功能是判断是否需要进行左旋转,右旋转或者颜色反转,最后需要一直保持根节点为黑色节点,过程如下图所示:

 1public:
2    void add(const Key &k, const Value &v)
3    {
4        _root = add(_root, k, v);
5        //最终根节点为黑色
6        _root->color = Node::BLACK;
7    }
8private:
9    /**
10     * 返回插入元素后红黑树的根
11     */

12        Node<Key, Value>* add(Node<Key, Value>* root, const Key &k, const Value &v)
13    {
14        if (root == nullptr)
15        {
16            _size++;
17            return new Node(k, v); 
18        }
19        if (k < root->key)
20        {
21            root->left = add(root->left, k, v);
22        }
23        else if(k > root->key)
24        {
25            root->right = add(root->right, k, v);
26        }
27        else
28        {
29            root->value = v;
30        }
31        // 左节点黑色,右节点红色
32        if (isRed(root->right) && !isRed(root->left))
33            root = rightRotate(root);
34        // 连续两个左子节点都是红色的,需要右旋转
35        if (isRed(root->left) && isRed(root->left->left))
36            root = rightRotate(root);
37         // 左右子树都是红节点,直接翻转颜色即可
38        if (isRed(root->left) && isRed(root->right))
39            flipColors(root);
40        return root;
41    }

设计架构

 1#ifndef __RBTREE_HPP
2#define __RBTREE_HPP
3//Author:Simon
4//Email:476941913@qq.com
5
6template<typename Key, typename Value>
7struct Node
8{

9    enum color { RED, BLACK };
10    Key key;
11    Value value;
12    int color;
13    Node *left;
14    Node *right;
15    Node(const Key &k,const Value &v):key(k),value(v),left(nullptr),right(nullptr),color(RED){}
16};
17
18template<typename Key,typename Value>
19class RBTree
20{

21public:
22    RBTree():_size(0),_root(nullptr);
23    ~RBTree();
24public:
25    void add(const Key &k, const Value &v);
26private:
27    Node<Key, Value>* leftRotate(Node<Key, Value> *node);
28    Node<Key, value>* rightRotate(Node<Key, Value>* node);
29    void flipColors(Node<Key, Value>* node);
30    bool isRed(Node<Key, Value>* node);
31    Node<Key, Value>* add(Node<Key, Value>* root, const Key &k, const Value &v);
32private:
33    int _size;
34    Node<Key, Value> *_root;
35};
36
37#endif // __RBTREE_HPP

以上是关于左旋转右旋转双旋的主要内容,如果未能解决你的问题,请参考以下文章

AVL树的插入与删除

算法导论 红黑树 实现

C++AVL树的实现--详细解析旋转细节

C++AVL树的实现--详细解析旋转细节

C语言编程 字符串的旋转(左旋右旋及判断)

图解:什么是旋转数组(Rotate Array)?