C++ Red-Black Tree (2) -------- Single Rotation of Red-Black Tree

1. The single rotation of the red-black tree includes turning left and turning right. The figure below is a left-rotating diagram. Look at how each node moves in detail.

 

The following figure shows the rotation result state diagram of the left and right single rotation

2. Then we will implement the red-black tree as shown in the figure below and perform a left and right rotation test

3. The code is as follows (following the code in the previous article: C++ red-black tree (1) -------- creation of red-black tree and insertion of Node )

 

#include <iostream>

using namespace std;

template < class T>
class RedBlackTree;  //红黑树

template <class T>
class RedBlackTreeNode; //红黑树节点


template <class T>
class RedBlackTree
{
	typedef RedBlackTreeNode<T> Node;

public:
	enum { BLACK, RED };

	RedBlackTree(const T &negInfo);  //构造函数主要初始化私有成员 header 和 nullNode
	~RedBlackTree();

	void insert(const T & x); //红黑树插入元素

	void rotateWithLeftChild(Node * & k2) const; //带着左孩子旋转即向右转 k2是旋转前的根节点

	void rotateWithRightChild(Node * &k1) const; //带着右孩子旋转即向左转 k1是旋转前的根节点

//private:
	Node *header; //header 的左子节点和右子节点初始化指向nullNode,将来右子节点会指向根节点,
				  //header节点的元素是个无效值
	Node *nullNode; //空节点

	Node *current; //当前节点
	Node *parent; //当前节点的父节点
	Node *grand; //当前节点的祖父节点
	Node *great; //当前节点的曾祖父节点

};


template <class T>
RedBlackTree<T>::RedBlackTree(const T &negInfo)
{
	nullNode = new Node();
	nullNode->left = nullNode->right = NULL;

	header = new Node(negInfo);
	header->left = header->right = nullNode; //header的左右节点初始化为nullNode
}

template <class T >
RedBlackTree<T>::~RedBlackTree()
{
	delete header;
	delete nullNode;
}

template <class T>
void RedBlackTree<T>::insert(const T &x)
{
	current = parent = grand = great = header; // 刚开始都指向头结点
	nullNode->element = x;  //空节点的元素等于新元素

	while (current->element != x)  //红黑树不允许有重复的节点
	{
		great = grand;        //一辈一辈往下循环
		grand = parent;
		parent = current;

		current = x > current->element ? current->right : current->left; //左大、右小
	}

	if (current != nullNode)
	{
		cout << "有重复元素了" << endl;

		return;
	}

	current = new Node(x, nullNode, nullNode);

	if (x < parent->element)
		parent->left = current;
	else
		parent->right = current;

	return;
}

template <class T>
void RedBlackTree<T>::rotateWithLeftChild(Node * & k2) const  //k2是旋转前的根节点
{
	Node * k1 = k2->left;

	k2->left = k1->right;
	k1->right = k2;

	k2 = k1;

}

template <class T>
void RedBlackTree<T>::rotateWithRightChild(Node * &k1) const //k1是旋转前的根节点
{
	Node *k2 = k1->right;

	k1->right = k2->left;
	k2->left = k1;
	k1 = k2;

}


template <class T>
class RedBlackTreeNode
{
	friend  RedBlackTree<T>;

public:
	RedBlackTreeNode(const T & ele = T(),
		RedBlackTreeNode* lf = NULL,
		RedBlackTreeNode *rg = NULL,
		int c = RedBlackTree<T>::BLACK) :element(ele), left(lf), right(rg), color(c)
	{};//红黑树节点构造函数
//private:
	RedBlackTreeNode *left;  //左子节点
	RedBlackTreeNode *right; //右子节点
	T element;				 //元素
	int color;				//节点颜色

};


void insert_test(void)
{
	cout << "insert_test" << endl;
	const int NEG_INFO = -9999;

	RedBlackTree<int> redBlackTree(NEG_INFO);

	redBlackTree.insert(30);
	redBlackTree.insert(15);
	redBlackTree.insert(70);
	redBlackTree.insert(20);

	cout << "原始数据:" << endl;
	cout << redBlackTree.header->right->element << endl;
	cout << redBlackTree.header->right->left->element << endl;
	cout << redBlackTree.header->right->right->element << endl;
	cout << redBlackTree.header->right->left->right->element << endl;
}

void single_rotate_test(void)
{
	cout << "single_rotate_test" << endl;
	const int NEG_INFO = -9999;
	RedBlackTree<int> redBlackTree(NEG_INFO);

	redBlackTree.insert(30);
	redBlackTree.insert(15);
	redBlackTree.insert(70);
	redBlackTree.insert(20);

	cout << "原始数据:" << endl;
	cout << redBlackTree.header->right->element << endl;
	cout << redBlackTree.header->right->left->element << endl;
	cout << redBlackTree.header->right->right->element << endl;
	cout << redBlackTree.header->right->left->right->element << endl;

	cout << "向右转:" << endl;
	redBlackTree.rotateWithLeftChild(redBlackTree.header->right);
	cout << redBlackTree.header->right->element << endl;
	cout << redBlackTree.header->right->right->element << endl;
	cout << redBlackTree.header->right->right->left->element << endl;
	cout << redBlackTree.header->right->right->right->element << endl;

	cout << "向左转:" << endl;
	redBlackTree.rotateWithRightChild(redBlackTree.header->right);
	cout << redBlackTree.header->right->element << endl;
	cout << redBlackTree.header->right->left->element << endl;
	cout << redBlackTree.header->right->right->element << endl;
	cout << redBlackTree.header->right->left->right->element << endl;
}

int main()
{
	//insert_test();
	single_rotate_test();

	return 0;
}

The results are as follows:

 

 

 

Guess you like

Origin blog.csdn.net/weixin_40204595/article/details/108104965