Red-Black-Tree
This commit is contained in:
		
							
								
								
									
										370
									
								
								BinaryTree/BalanceTree/Red-Black Tree/RBTree.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								BinaryTree/BalanceTree/Red-Black Tree/RBTree.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,370 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include "TreeNode.h"
 | 
			
		||||
template <class T>
 | 
			
		||||
class RBTree {
 | 
			
		||||
private:
 | 
			
		||||
	TreeNode<T>* root;
 | 
			
		||||
	TreeNode<T>* nul;
 | 
			
		||||
	int size;
 | 
			
		||||
 | 
			
		||||
	void initNul() {
 | 
			
		||||
		nul = new TreeNode<T>(0, nul, nul, nul);
 | 
			
		||||
		nul->color = Color::RED;
 | 
			
		||||
	}
 | 
			
		||||
	void inorder(TreeNode<T>* x);
 | 
			
		||||
	void dispose(TreeNode<T>* x) {
 | 
			
		||||
		if (x == nullptr || x == nul) return;
 | 
			
		||||
		dispose(x->left);
 | 
			
		||||
		dispose(x->right);
 | 
			
		||||
		delete x;
 | 
			
		||||
		//<2F>ص㲻<D8B5><E3B2BB>delete nul<75><6C><EFBFBD><EFBFBD>Ϊȫ<CEAA>ֵ<EFBFBD><D6B5>ڱ<EFBFBD><DAB1><EFBFBD>
 | 
			
		||||
	}
 | 
			
		||||
public:
 | 
			
		||||
	RBTree() : size(0) { initNul(); root = nul; }
 | 
			
		||||
	RBTree(TreeNode<T>* r, int s) : root(r), size(s) { initNul(); }
 | 
			
		||||
	~RBTree() {
 | 
			
		||||
		dispose(root);
 | 
			
		||||
		root = nullptr;
 | 
			
		||||
		delete nul;
 | 
			
		||||
		//ɾ<><C9BE><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD><EFBFBD><EFBFBD>Ҫɾ<D2AA><C9BE>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TreeNode<T>* RotateLeft(TreeNode<T>* x);//RR
 | 
			
		||||
	TreeNode<T>* RotateRight(TreeNode<T>* x);//LL
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	void insert(const T& e);
 | 
			
		||||
	void fixinsert(TreeNode<T>* x);
 | 
			
		||||
	void fixdelete(TreeNode<T>* x);
 | 
			
		||||
	void inorder() { inorder(root); }
 | 
			
		||||
	void erase(const T& e);
 | 
			
		||||
	TreeNode<T>* find(const T& e);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline TreeNode<T>* RBTree<T>::RotateLeft(TreeNode<T>* x) {
 | 
			
		||||
	TreeNode<T>* y = x->right;       // <20>Һ<EFBFBD><D2BA><EFBFBD>
 | 
			
		||||
	TreeNode<T>* T2 = y->left;       // y <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>
 | 
			
		||||
 | 
			
		||||
	// <20><><EFBFBD><EFBFBD>
 | 
			
		||||
	y->left = x;
 | 
			
		||||
	x->right = T2;
 | 
			
		||||
 | 
			
		||||
	// <20><><EFBFBD><EFBFBD> parent ָ<><D6B8>
 | 
			
		||||
	if (T2) T2->parent = x;          // <20><><EFBFBD><EFBFBD> T2 <20><><EFBFBD><EFBFBD>
 | 
			
		||||
	y->parent = x->parent;           // y <20><><EFBFBD><EFBFBD> x <20>ĸ<EFBFBD><C4B8>ڵ<EFBFBD>
 | 
			
		||||
 | 
			
		||||
	if (x->parent == nul) {      // x <20>Ǹ<EFBFBD><C7B8>ڵ<EFBFBD>
 | 
			
		||||
		root = y;
 | 
			
		||||
	}
 | 
			
		||||
	else if (x == x->parent->left) {
 | 
			
		||||
		x->parent->left = y;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		x->parent->right = y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	x->parent = y;
 | 
			
		||||
 | 
			
		||||
	return y;                        // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
TreeNode<T>* RBTree<T>::RotateRight(TreeNode<T>* x) {
 | 
			
		||||
	//<2F><>parent<6E><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ݹ飬ֱ<E9A3AC><D6B1><EFBFBD><EFBFBD>parent
 | 
			
		||||
	TreeNode<T>* y = x->left;        
 | 
			
		||||
	TreeNode<T>* T2 = y->right;      
 | 
			
		||||
 | 
			
		||||
	// <20><>ת
 | 
			
		||||
	y->right = x;
 | 
			
		||||
	x->left = T2;
 | 
			
		||||
 | 
			
		||||
	// <20><><EFBFBD><EFBFBD> parent ָ<><D6B8>
 | 
			
		||||
	if (T2) T2->parent = x;          // <20><><EFBFBD><EFBFBD> T2 <20><><EFBFBD><EFBFBD>
 | 
			
		||||
	y->parent = x->parent;           // y <20><><EFBFBD><EFBFBD> x <20>ĸ<EFBFBD><C4B8>ڵ<EFBFBD>
 | 
			
		||||
 | 
			
		||||
	if (x->parent == nul) {      // x <20>Ǹ<EFBFBD><C7B8>ڵ<EFBFBD>
 | 
			
		||||
		root = y;
 | 
			
		||||
	}
 | 
			
		||||
	else if (x == x->parent->left) {
 | 
			
		||||
		x->parent->left = y;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		x->parent->right = y;
 | 
			
		||||
	}
 | 
			
		||||
	x->parent = y;
 | 
			
		||||
	return y;                        // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void RBTree<T>::inorder(TreeNode<T>* x)
 | 
			
		||||
{
 | 
			
		||||
	if (x == nul) return;
 | 
			
		||||
	inorder(x->left);
 | 
			
		||||
	std::cout << x->element << " ";
 | 
			
		||||
	inorder(x->right);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void RBTree<T>::insert(const T& e)
 | 
			
		||||
{
 | 
			
		||||
	TreeNode<T>* p = new TreeNode<T>(e, nul, nul, nul);
 | 
			
		||||
 | 
			
		||||
	TreeNode<T>* current = root;
 | 
			
		||||
	TreeNode<T>* parent = nul;
 | 
			
		||||
	//BST<53><54><EFBFBD>룬<EFBFBD><EBA3AC>parent<6E>Ͳ<EFBFBD><CDB2><EFBFBD>Ҫ<EFBFBD>ݹ<EFBFBD><DDB9>ڵ<EFBFBD><DAB5><EFBFBD>
 | 
			
		||||
	while (current != nul) {
 | 
			
		||||
		parent = current;
 | 
			
		||||
		if (e < parent->element) current = parent->left;
 | 
			
		||||
		else current = parent->right;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p->parent = parent;
 | 
			
		||||
	if (parent == nul) root = p;
 | 
			
		||||
	if (parent == nul) root = p;
 | 
			
		||||
	else if (e < parent->element) parent->left = p;
 | 
			
		||||
	else parent->right = p;
 | 
			
		||||
 | 
			
		||||
	//FixInsert
 | 
			
		||||
	fixinsert(p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void RBTree<T>::fixinsert(TreeNode<T>* x)
 | 
			
		||||
{
 | 
			
		||||
	while (x != root && x->parent->color == Color::RED) {
 | 
			
		||||
		//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
		if (x->parent->parent->left == x->parent) {
 | 
			
		||||
			//<2F><><EFBFBD>ڵ<EFBFBD>
 | 
			
		||||
			if (x->parent->parent->right->color == Color::RED) {
 | 
			
		||||
				//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
				x->parent->color = x->parent->parent->right->color = Color::BLACK;
 | 
			
		||||
				x->parent->parent->color = Color::RED;
 | 
			
		||||
				//fixinsert(x->parent->parent);<3B>ݹ鲻<DDB9>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8>жϣ<D0B6><CFA3><EFBFBD><EFBFBD>״<EFBFBD><D7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>ɫ
 | 
			
		||||
				x = x->parent->parent;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (x == x->parent->left) {
 | 
			
		||||
				//LL//<2F>ȱ<EFBFBD>ɫ<EFBFBD>游<EFBFBD><E6B8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
				x->parent->parent->color = Color::RED;
 | 
			
		||||
				x->parent->color = Color::BLACK;
 | 
			
		||||
				//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
				RotateRight(x->parent->parent);
 | 
			
		||||
			}
 | 
			
		||||
			//LR
 | 
			
		||||
			if (x == x->parent->right) {
 | 
			
		||||
				//<2F><><EFBFBD><EFBFBD>LL
 | 
			
		||||
				x = x->parent;
 | 
			
		||||
				RotateLeft(x);
 | 
			
		||||
				//<2F><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>LL<4C>ˣ<EFBFBD><CBA3><EFBFBD>һ<EFBFBD><D2BB>ѭ<EFBFBD><D1AD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>LL
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		//else<73>Գ<EFBFBD><D4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ҽڵ<D2BD>
 | 
			
		||||
		else {
 | 
			
		||||
			//1-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
			if (x->parent->parent->left->color == Color::RED) {
 | 
			
		||||
				x->parent->parent->left->color = Color::BLACK;
 | 
			
		||||
				x->parent->color = Color::BLACK;
 | 
			
		||||
				x->parent->parent->color = Color::RED;
 | 
			
		||||
				x = x->parent->parent;
 | 
			
		||||
			}
 | 
			
		||||
			//2-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
			else {
 | 
			
		||||
				//2-1-RL -> <20><><EFBFBD><EFBFBD>ΪRR<52><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
				if (x == x->parent->left) {
 | 
			
		||||
					x = x->parent;
 | 
			
		||||
					RotateRight(x);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				//3-RR<52><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2-1
 | 
			
		||||
				x->parent->color = Color::BLACK;
 | 
			
		||||
				x->parent->parent->color = Color::RED;
 | 
			
		||||
				RotateLeft(x->parent->parent);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	root->color = Color::BLACK;
 | 
			
		||||
}
 | 
			
		||||
// x <20><>ʾ<EFBFBD><CABE>ɾ<EFBFBD><C9BE><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㣨<DAB5><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> nul <20>ڱ<EFBFBD><DAB1><EFBFBD>
 | 
			
		||||
// ֻ<>е<EFBFBD><D0B5><EFBFBD>ɾ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5>Ǻ<EFBFBD>ɫʱ<C9AB><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD> fixdelete
 | 
			
		||||
template<class T>
 | 
			
		||||
void RBTree<T>::fixdelete(TreeNode<T>* x) {
 | 
			
		||||
	while (x != root && x->color == Color::BLACK) {
 | 
			
		||||
		// <20><><EFBFBD><EFBFBD>1<EFBFBD><31>x <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
		if (x == x->parent->left) {
 | 
			
		||||
			TreeNode<T>* w = x->parent->right;  // x <20><><EFBFBD>ֵܽڵ<DCBD>
 | 
			
		||||
 | 
			
		||||
			// case 1: <20>ֵ<EFBFBD><D6B5>Ǻ<EFBFBD>ɫ
 | 
			
		||||
			// -> <20><><EFBFBD>ֵ<EFBFBD>Ⱦ<EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>죬Ȼ<ECA3AC><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
			// -> ת<><D7AA>Ϊ<EFBFBD>ֵ<EFBFBD><D6B5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
			if (w->color == Color::RED) {
 | 
			
		||||
				w->color = Color::BLACK;
 | 
			
		||||
				x->parent->color = Color::RED;
 | 
			
		||||
				RotateLeft(x->parent);
 | 
			
		||||
				w = x->parent->right;  // <20><><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// case 2: <20>ֵ<EFBFBD><D6B5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ӣ<EFBFBD>w->left, w->right<68><74><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ
 | 
			
		||||
			// -> <20><><EFBFBD>ֵ<EFBFBD>Ⱦ<EFBFBD>죬<EFBFBD>൱<EFBFBD>ڰ<EFBFBD> "<22><><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD>ɫ" <20><><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD>
 | 
			
		||||
			// -> <20><EFBFBD><DEB8><EFBFBD><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻ<EFBFBD><CFBD><EFBFBD>
 | 
			
		||||
			if (w->left->color == Color::BLACK && w->right->color == Color::BLACK) {
 | 
			
		||||
				w->color = Color::RED;
 | 
			
		||||
				x = x->parent;  // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				// case 3: <20>ֵ<EFBFBD><D6B5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>ֵܵ<D6B5><DCB5>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ
 | 
			
		||||
				// -> <20>Ȱ<EFBFBD><C8B0>ֵ<EFBFBD>Ⱦ<EFBFBD>죬<EFBFBD><ECA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>ڣ<EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>
 | 
			
		||||
				// -> ת<><D7AA>Ϊ case 4
 | 
			
		||||
				if (w->right->color == Color::BLACK) {
 | 
			
		||||
					w->left->color = Color::BLACK;
 | 
			
		||||
					w->color = Color::RED;
 | 
			
		||||
					RotateRight(w);
 | 
			
		||||
					w = x->parent->right;  // <20><><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// case 4: <20>ֵ<EFBFBD><D6B5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>ֵܵ<D6B5><DCB5>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD>Ǻ<EFBFBD>ɫ
 | 
			
		||||
				// -> <20><><EFBFBD>ֵ<EFBFBD><D6B5>滻<EFBFBD><E6BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>ڣ<EFBFBD><DAA3>ֵܵ<D6B5><DCB5>Һ<EFBFBD><D2BA><EFBFBD>Ⱦ<EFBFBD><C8BE>
 | 
			
		||||
				// -> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ף<EFBFBD><D7A3><EFBFBD><DEB8><EFBFBD><EFBFBD>ɣ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>˳<EFBFBD>ѭ<EFBFBD><D1AD>
 | 
			
		||||
				w->color = x->parent->color;
 | 
			
		||||
				x->parent->color = Color::BLACK;
 | 
			
		||||
				w->right->color = Color::BLACK;
 | 
			
		||||
				RotateLeft(x->parent);
 | 
			
		||||
				x = root;  // <20><><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// <20><><EFBFBD><EFBFBD>2<EFBFBD><32>x <20><><EFBFBD>Һ<EFBFBD><D2BA>ӣ<EFBFBD><D3A3>Գ<EFBFBD><D4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
		else {
 | 
			
		||||
			TreeNode<T>* w = x->parent->left;
 | 
			
		||||
 | 
			
		||||
			if (w->color == Color::RED) {
 | 
			
		||||
				w->color = Color::BLACK;
 | 
			
		||||
				x->parent->color = Color::RED;
 | 
			
		||||
				RotateRight(x->parent);
 | 
			
		||||
				w = x->parent->left;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (w->right->color == Color::BLACK && w->left->color == Color::BLACK) {
 | 
			
		||||
				w->color = Color::RED;
 | 
			
		||||
				x = x->parent;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (w->left->color == Color::BLACK) {
 | 
			
		||||
					w->right->color = Color::BLACK;
 | 
			
		||||
					w->color = Color::RED;
 | 
			
		||||
					RotateLeft(w);
 | 
			
		||||
					w = x->parent->left;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				w->color = x->parent->color;
 | 
			
		||||
				x->parent->color = Color::BLACK;
 | 
			
		||||
				w->left->color = Color::BLACK;
 | 
			
		||||
				RotateRight(x->parent);
 | 
			
		||||
				x = root;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤ x <20>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD> nul<75><6C>
 | 
			
		||||
	x->color = Color::BLACK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
inline void RBTree<T>::erase(const T& e)
 | 
			
		||||
{
 | 
			
		||||
	TreeNode<T>* z = find(e);
 | 
			
		||||
	//1-BSTɾ<54><C9BE><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3>ұ<EFBFBD><D2B1>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
	TreeNode<T>* y = z;                 // ʵ<><CAB5>Ҫɾ<D2AA><C9BE><EFBFBD>Ľڵ㣨<DAB5><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z<><7A>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z <20>ĺ<EFBFBD><C4BA>̣<EFBFBD>
 | 
			
		||||
	TreeNode<T>* x;                     // y <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㣨<DAB5><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӽڵ㣬Ҳ<E3A3AC><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> nul<75><6C>
 | 
			
		||||
	Color yOriginalColor = y->color;    // <20><>¼ y <20><>ԭʼ<D4AD><CABC>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ fixdelete
 | 
			
		||||
	// case 1: z û<><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z
 | 
			
		||||
	if (z->left == nul) {
 | 
			
		||||
		x = z->right;                 // <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
 | 
			
		||||
		// <20><> z <20>Ӹ<EFBFBD><D3B8>Ͽ<D7B6>
 | 
			
		||||
		if (z->parent == nul) root = x;
 | 
			
		||||
		else if (z == z->parent->left) z->parent->left = x;
 | 
			
		||||
		else z->parent->right = x;
 | 
			
		||||
		x->parent = z->parent;
 | 
			
		||||
	}
 | 
			
		||||
	// case 2: z û<><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z
 | 
			
		||||
	else if (z->right == nul) {
 | 
			
		||||
		x = z->left;
 | 
			
		||||
		if (z->parent == nul) root = x;
 | 
			
		||||
		else if (z == z->parent->left) z->parent->left = x;
 | 
			
		||||
		else z->parent->right = x;
 | 
			
		||||
		x->parent = z->parent;
 | 
			
		||||
	}
 | 
			
		||||
	// case 3: z <20><><EFBFBD>Һ<EFBFBD><D2BA>Ӷ<EFBFBD><D3B6><EFBFBD> -> <20>ҵ<EFBFBD> z <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
	else {
 | 
			
		||||
		// <20><> z <20>ĺ<EFBFBD><C4BA>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㣩
 | 
			
		||||
		y = z->right;
 | 
			
		||||
		while (y->left != nul) y = y->left;
 | 
			
		||||
		yOriginalColor = y->color;   // <20><>¼<EFBFBD><C2BC><EFBFBD>̵<EFBFBD><CCB5><EFBFBD>ɫ
 | 
			
		||||
		x = (y->right != nul ? y->right : nul);  // <20><><EFBFBD>̵<EFBFBD><CCB5>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
 | 
			
		||||
 | 
			
		||||
		// <20><><EFBFBD><EFBFBD> y <20><><EFBFBD><EFBFBD> z <20><>ֱ<EFBFBD><D6B1><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD>
 | 
			
		||||
		if (y->parent != z) {
 | 
			
		||||
			// <20><> y->right <20><><EFBFBD><EFBFBD> y
 | 
			
		||||
			if (y->parent->left == y) y->parent->left = x;
 | 
			
		||||
			else y->parent->right = x;
 | 
			
		||||
			x->parent = y->parent;
 | 
			
		||||
 | 
			
		||||
			// <20><> z->right <20>ҵ<EFBFBD> y <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
			y->right = z->right;
 | 
			
		||||
			y->right->parent = y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// <20><> z->left <20>ҵ<EFBFBD> y <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
		if (z->parent == nul) root = y;
 | 
			
		||||
		else if (z == z->parent->left) z->parent->left = y;
 | 
			
		||||
		else z->parent->right = y;
 | 
			
		||||
		y->parent = z->parent;
 | 
			
		||||
 | 
			
		||||
		y->left = z->left;
 | 
			
		||||
		y->left->parent = y;
 | 
			
		||||
		y->color = z->color;
 | 
			
		||||
	}
 | 
			
		||||
	delete z;
 | 
			
		||||
 | 
			
		||||
	//2-RBT<42><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
	// <20><><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>ʵ<EFBFBD>ʽڵ<CABD><DAB5>Ǻ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD><C6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> fixdelete
 | 
			
		||||
	if (yOriginalColor == Color::BLACK) {
 | 
			
		||||
		fixdelete(x);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
template<class T>
 | 
			
		||||
inline TreeNode<T>* RBTree<T>::find(const T& e)
 | 
			
		||||
{
 | 
			
		||||
	TreeNode<T>* p = root;
 | 
			
		||||
	while (p != nul) {
 | 
			
		||||
		if (e < p->element) p = p->left;
 | 
			
		||||
		else if (e > p->element) p = p->right;
 | 
			
		||||
		else break;
 | 
			
		||||
	}
 | 
			
		||||
	if (!p) p = nul;
 | 
			
		||||
	return p;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
<EFBFBD>Ƽ<EFBFBD>д<EFBFBD><EFBFBD>
 | 
			
		||||
if (x->parent == x->parent->parent->left) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
			TreeNode<T>* y = x->parent->parent->right; // <20><><EFBFBD><EFBFBD>
 | 
			
		||||
			if (y->color == Color::RED) { // Case 1: <20><><EFBFBD><EFBFBD>
 | 
			
		||||
				x->parent->color = Color::BLACK;
 | 
			
		||||
				y->color = Color::BLACK;
 | 
			
		||||
				x->parent->parent->color = Color::RED;
 | 
			
		||||
				x = x->parent->parent; // <20><><EFBFBD><EFBFBD><EFBFBD>游
 | 
			
		||||
			} else {
 | 
			
		||||
				if (x == x->parent->right) { // Case 2: LR
 | 
			
		||||
					x = x->parent;
 | 
			
		||||
					RotateLeft(x);
 | 
			
		||||
				}
 | 
			
		||||
				// Case 3: LL
 | 
			
		||||
				x->parent->color = Color::BLACK;
 | 
			
		||||
				x->parent->parent->color = Color::RED;
 | 
			
		||||
				RotateRight(x->parent->parent);
 | 
			
		||||
			}
 | 
			
		||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD>else<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ҽڵ㣩<EFBFBD><EFBFBD>˼·
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										263
									
								
								BinaryTree/BalanceTree/Red-Black Tree/README.MD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								BinaryTree/BalanceTree/Red-Black Tree/README.MD
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,263 @@
 | 
			
		||||
[TOC]
 | 
			
		||||
## 红黑树插入思路
 | 
			
		||||
好的,我们把 **红黑树插入的完整逻辑**整理一下,分步骤、分情况讲,保证清晰易懂:
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 🔹 红黑树插入逻辑
 | 
			
		||||
 | 
			
		||||
### 1️⃣ 基本步骤
 | 
			
		||||
 | 
			
		||||
1. **普通 BST 插入**
 | 
			
		||||
 | 
			
		||||
   * 按二叉搜索树的规则,把新节点 `x` 插入到合适位置。
 | 
			
		||||
   * 新节点初始化为 **红色**(因为插入红色节点更容易维持黑高)。
 | 
			
		||||
 | 
			
		||||
2. **判断是否需要修复**
 | 
			
		||||
``` cpp
 | 
			
		||||
插入新节点 z (红色)
 | 
			
		||||
|
 | 
			
		||||
+-- 父是黑色 → OK,直接插入
 | 
			
		||||
|
 | 
			
		||||
+-- 父是红色
 | 
			
		||||
     |
 | 
			
		||||
     +-- 叔叔是红色 → 父黑叔黑,祖红,上移到祖父,继续检查
 | 
			
		||||
     |
 | 
			
		||||
     +-- 叔叔是黑色
 | 
			
		||||
          |
 | 
			
		||||
          +-- z 在父的同向(左左或右右) → Case 3,旋转 + 颜色交换
 | 
			
		||||
          +-- z 在父的异向(左右或右左) → Case 2,先旋转父,再变为同向,继续 Case 3
 | 
			
		||||
```
 | 
			
		||||
   * 如果父节点是黑色 → 红黑性质不破坏,不需要 fix。
 | 
			
		||||
   * 如果父节点是红色 → 违反“红色节点不能有红色子节点”,需要修复。
 | 
			
		||||
   * 考虑叔叔是不是红的
 | 
			
		||||
   * ->叔叔是红的就 一起变黑,祖父变红
 | 
			
		||||
   * ->叔叔不是红的,考虑旋转+变色
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 2️⃣ fixinsert 修复逻辑
 | 
			
		||||
 | 
			
		||||
设:
 | 
			
		||||
 | 
			
		||||
* `x` = 当前插入节点
 | 
			
		||||
* `p` = 父节点
 | 
			
		||||
* `u` = 叔叔节点(父节点的兄弟)
 | 
			
		||||
* `g` = 祖父节点
 | 
			
		||||
 | 
			
		||||
#### **情况 1:叔叔节点是红色**
 | 
			
		||||
 | 
			
		||||
* **条件**:`p` 是红色,`u` 是红色
 | 
			
		||||
* **处理**:
 | 
			
		||||
 | 
			
		||||
  1. 父节点 `p` 染黑
 | 
			
		||||
  2. 叔叔节点 `u` 染黑
 | 
			
		||||
  3. 祖父节点 `g` 染红
 | 
			
		||||
  4. 将 `x` 上移到祖父节点 `g`,继续循环判断
 | 
			
		||||
* **原因**:通过重新染色,把红红冲突上移,保持黑高不变
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
#### **情况 2:叔叔节点是黑色**
 | 
			
		||||
 | 
			
		||||
* **条件**:`p` 是红色,`u` 是黑色
 | 
			
		||||
* **子情况**(根据 `x` 在父节点的左右位置):
 | 
			
		||||
 | 
			
		||||
1. **左-左(LL)**
 | 
			
		||||
 | 
			
		||||
   * `x` 是 `p` 的左孩子,`p` 是 `g` 的左孩子
 | 
			
		||||
   * **处理**:
 | 
			
		||||
 | 
			
		||||
     1. 父节点染黑,祖父染红
 | 
			
		||||
     2. 右旋祖父
 | 
			
		||||
 | 
			
		||||
2. **左-右(LR)**
 | 
			
		||||
 | 
			
		||||
   * `x` 是 `p` 的右孩子,`p` 是 `g` 的左孩子
 | 
			
		||||
   * **处理**:
 | 
			
		||||
 | 
			
		||||
     1. 左旋父节点(将 LR 转化为 LL)
 | 
			
		||||
     2. 再执行 LL 情况的右旋 + 染色
 | 
			
		||||
 | 
			
		||||
3. **右-右(RR)**
 | 
			
		||||
 | 
			
		||||
   * 对称 LL:右孩子的右孩子插入
 | 
			
		||||
   * 左旋祖父 + 调整颜色
 | 
			
		||||
 | 
			
		||||
4. **右-左(RL)**
 | 
			
		||||
 | 
			
		||||
   * 对称 LR:右孩子的左孩子插入
 | 
			
		||||
   * 右旋父节点 → 变成 RR → 左旋祖父 + 调整颜色
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 3️⃣ 循环终止
 | 
			
		||||
 | 
			
		||||
* 当父节点是黑色,或者到达根节点,循环结束
 | 
			
		||||
* 最后 **根节点必须染黑**
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 🔹 总结关键点
 | 
			
		||||
 | 
			
		||||
1. **新节点红色** → 保持黑高不变
 | 
			
		||||
2. **红红冲突** → 根据叔叔颜色分两类处理:
 | 
			
		||||
 | 
			
		||||
   * 红色叔叔 → 上移染色
 | 
			
		||||
   * 黑色叔叔 → 旋转 + 染色
 | 
			
		||||
3. **旋转 + 染色** → 只改变局部结构,保持整体 BST 和红黑性质
 | 
			
		||||
4. **根节点保持黑色** → 保证树的黑高一致
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
如果你需要,我可以帮你画一张 **红黑树插入示意图**,把 LL/LR/RR/RL 四种旋转场景和颜色变化可视化,看起来非常直观。
 | 
			
		||||
 | 
			
		||||
你想让我画吗?
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 红黑树删除思路
 | 
			
		||||
好,我给你梳理一下 **红黑树删除的整体思路**,只讲逻辑,不贴代码:
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 1️⃣ 找到要删除的节点
 | 
			
		||||
 | 
			
		||||
* 首先按照普通二叉搜索树(BST)查找待删除节点 `z`。
 | 
			
		||||
* 如果节点不存在,就结束。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 2️⃣ 分情况处理节点
 | 
			
		||||
 | 
			
		||||
红黑树删除跟 BST 删除类似,分三种情况:
 | 
			
		||||
 | 
			
		||||
1. **节点没有子节点(叶子)**
 | 
			
		||||
 | 
			
		||||
   * 直接把它从父节点断开。
 | 
			
		||||
   * 如果节点是黑色,删除会破坏黑高,需要修复。
 | 
			
		||||
 | 
			
		||||
2. **节点只有一个孩子**
 | 
			
		||||
 | 
			
		||||
   * 用唯一的孩子替代该节点挂到父节点上。
 | 
			
		||||
   * 如果删除的是黑色节点,也可能破坏红黑性质,需要修复。
 | 
			
		||||
 | 
			
		||||
3. **节点有两个孩子**
 | 
			
		||||
 | 
			
		||||
   * 找该节点的 **中序后继**(右子树最左的节点)替代它。
 | 
			
		||||
   * 删除后继节点(后继最多有一个右孩子),这一步退化为情况 1 或 2。
 | 
			
		||||
   * 然后把被删除节点的左右孩子接到后继上,继承颜色。
 | 
			
		||||
   * 如果后继原本是黑色,也需要修复。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 3️⃣ 修复红黑树性质
 | 
			
		||||
 | 
			
		||||
* 删除黑色节点或用黑色节点替代时,会破坏 **黑高** 或 **红黑性质**。
 | 
			
		||||
* 修复核心思路:
 | 
			
		||||
 | 
			
		||||
  1. **兄弟节点红色** → 旋转并调整颜色,使兄弟变黑。
 | 
			
		||||
  2. **兄弟黑色,兄弟的孩子都是黑色** → 兄弟染红,把“双重黑”向上传递。
 | 
			
		||||
  3. **兄弟黑色,有红色侄子** → 旋转 + 染色,直接消除双重黑。
 | 
			
		||||
* 修复循环一直执行,直到双重黑消除或者到达根节点。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 4️⃣ 特别注意
 | 
			
		||||
 | 
			
		||||
* 根节点始终要保持黑色。
 | 
			
		||||
* 删除过程尽量使用 **哨兵节点 `nul`** 替代空指针,避免每次判断 `nullptr`。
 | 
			
		||||
* 删除逻辑主要是 **BST 替换 + fixdelete 修复** 两步结合。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
简单总结一句话就是:
 | 
			
		||||
 | 
			
		||||
**“先按 BST 删除节点,再根据被删节点颜色决定是否修复,用旋转和染色处理双重黑。”**
 | 
			
		||||
 | 
			
		||||
好,我们把 **红黑树删除后修复的核心步骤**细化讲解一下,把每种情况的逻辑和原因都拆开看。假设删除后出现的节点 `x` 带有 **“双重黑”(double black)**,这是修复的触发条件。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 🔹 修复红黑树性质(Double Black 处理)
 | 
			
		||||
 | 
			
		||||
### 情景概念
 | 
			
		||||
 | 
			
		||||
* 删除或替代节点是黑色 → 破坏了红黑树的黑高。
 | 
			
		||||
* 我们用 `x` 表示替代节点(可能是哨兵 `nul`)。
 | 
			
		||||
* `w` 表示 `x` 的兄弟节点。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### **情况 1:兄弟节点红色**
 | 
			
		||||
 | 
			
		||||
**条件**:`w->color == RED`
 | 
			
		||||
 | 
			
		||||
**处理逻辑**:
 | 
			
		||||
 | 
			
		||||
1. 把兄弟染黑,父节点染红。
 | 
			
		||||
2. 对父节点做旋转(左旋或右旋,视 x 在左还是右)。
 | 
			
		||||
3. 转换成“兄弟是黑色”的情况,进入下一轮循环处理。
 | 
			
		||||
 | 
			
		||||
**原因**:
 | 
			
		||||
 | 
			
		||||
* 红色兄弟意味着父节点必然是黑色(红黑性质),旋转后可以让黑高平衡,同时把问题转化为更容易处理的兄弟黑色情况。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### **情况 2:兄弟是黑色且兄弟两个孩子都是黑色**
 | 
			
		||||
 | 
			
		||||
**条件**:`w->color == BLACK && w->left->color == BLACK && w->right->color == BLACK`
 | 
			
		||||
 | 
			
		||||
**处理逻辑**:
 | 
			
		||||
 | 
			
		||||
1. 把兄弟染红。
 | 
			
		||||
2. 把 x 的双重黑向父节点传递:`x = x->parent`,循环继续。
 | 
			
		||||
 | 
			
		||||
**原因**:
 | 
			
		||||
 | 
			
		||||
* 黑高减少发生在 x 所在的路径上。
 | 
			
		||||
* 兄弟的两个子节点都是黑色 → 黑高没法补偿,只能把多余的黑色“向上递归”。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### **情况 3:兄弟是黑色且有红色侄子**
 | 
			
		||||
 | 
			
		||||
**条件**:`w->color == BLACK` 且至少有一个子节点红色
 | 
			
		||||
 | 
			
		||||
**处理逻辑**:
 | 
			
		||||
 | 
			
		||||
1. 如果 x 是左孩子:
 | 
			
		||||
 | 
			
		||||
   * case RL:先对兄弟右旋,让红色侄子转到右侧。
 | 
			
		||||
   * case RR:父亲左旋,同时调整父亲、兄弟和红色侄子的颜色。
 | 
			
		||||
2. 对称地,如果 x 是右孩子:
 | 
			
		||||
 | 
			
		||||
   * case LR:先左旋兄弟
 | 
			
		||||
   * case LL:父亲右旋 + 染色
 | 
			
		||||
 | 
			
		||||
**原因**:
 | 
			
		||||
 | 
			
		||||
* 红色侄子可以“补偿”被删除黑色节点造成的黑高缺失。
 | 
			
		||||
* 通过旋转和染色,双重黑立即消除,红黑树性质恢复。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 🔹 循环结束条件
 | 
			
		||||
 | 
			
		||||
* 双重黑消除(x 被重新染黑或者到达根节点)。
 | 
			
		||||
* 根节点必须保持黑色 → 最后再显式设置 `root->color = BLACK`。
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
💡 **直观理解**:
 | 
			
		||||
 | 
			
		||||
1. **红兄弟** → 转化问题
 | 
			
		||||
2. **黑兄弟+黑侄子** → 往上递
 | 
			
		||||
3. **黑兄弟+红侄子** → 补偿黑高,立即解决
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
如果你想,我可以画一张 **删除修复流程图**,用节点颜色标注每一步的旋转和染色,直观展示三种情况。
 | 
			
		||||
 | 
			
		||||
你希望我画吗?
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								BinaryTree/BalanceTree/Red-Black Tree/TreeNode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								BinaryTree/BalanceTree/Red-Black Tree/TreeNode.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
enum Color { RED, BLACK };
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
class TreeNode {
 | 
			
		||||
public:
 | 
			
		||||
	T element;
 | 
			
		||||
	TreeNode<T>* left;
 | 
			
		||||
	TreeNode<T>* right;
 | 
			
		||||
	TreeNode<T>* parent;
 | 
			
		||||
	Color color;
 | 
			
		||||
 | 
			
		||||
	TreeNode() : left(nullptr), right(nullptr), parent(nullptr), color(Color::RED) {}
 | 
			
		||||
	TreeNode(const T& e) : element(e), left(nullptr), right(nullptr), parent(nullptr), color(Color::RED) {}
 | 
			
		||||
	TreeNode(const T& e, TreeNode<T>* l, TreeNode<T>* r, TreeNode<T>* p) : element(e), left(l), right(r), parent(p), color(Color::RED) {}
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										21
									
								
								BinaryTree/BalanceTree/Red-Black Tree/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								BinaryTree/BalanceTree/Red-Black Tree/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
#include "RBTree.h"
 | 
			
		||||
using namespace std;
 | 
			
		||||
int main() {
 | 
			
		||||
	RBTree<int> t;
 | 
			
		||||
	//һ<><D2BB><EFBFBD><EFBFBD>עNILָ<4C><D6B8><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>Ľڵ㶼Ҫ<E3B6BC><D2AA>NIL
 | 
			
		||||
	t.insert(8);
 | 
			
		||||
	t.insert(5);
 | 
			
		||||
	t.insert(3);
 | 
			
		||||
	t.insert(2);
 | 
			
		||||
	t.insert(7);
 | 
			
		||||
	t.insert(1);
 | 
			
		||||
	t.inorder();
 | 
			
		||||
	cout << endl;
 | 
			
		||||
	t.erase(7);
 | 
			
		||||
	t.inorder();
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
1 2 3 5 7 8
 | 
			
		||||
1 2 3 5 8
 | 
			
		||||
*/
 | 
			
		||||
		Reference in New Issue
	
	Block a user