红黑树代码实现

请对照红黑树原剖析一起看,如要问题,请各位大神不吝赐教

//网页测试工具   https://www.cs.usfca.edu/~galles/visualization/RedBlack.html


#include <assert.h>
#include <iostream>

using namespace  std;

#define RED		1
#define BLACK	2

template<typename T>
class Node
{
public:
	Node()
	{
	}
	inline operator T& ()
	{
		return data_;
	}

	T data_;
	int color_; //节点颜色
	Node<T>* left_; //左节点
	Node<T>* right_;//右节点
	Node<T>* parent_;//父节点
};

template <typename T>
class RBTree
{
public:
	RBTree()
	{
		tree_ = NULL;
//		count_ = 0;
	}

	virtual ~RBTree()
	{
		clear();
//		count_ = 0;
	}

	//清空AVLTree
	virtual void clear(Node<T>* node = NULL)
	{
		if (!node) node = tree_;

		if (!node) return;
		Node<T>* left = node->left_;
		Node<T>* right = node->right_;
		delete node;
		node = NULL;
		//这里还要去释放自己类内申请的内存
		{
			if (left)
				clear(left);
			if (right)
				clear(right);
		}
	}

	inline Node<T>* allocNode(const T& value)
	{
		Node<T>* newNode = new Node<T>;
		newNode->data_ = value;
		newNode->left_ = newNode->right_ = NULL;
		newNode->parent_ = NULL;
		setColor(newNode, RED);

		return newNode;
	}

	inline int height(Node<T>* node)
	{
		if (node == NULL)
		{
			return 0;
		}
		int rightheight = height(node->right_);
		int leftheight = height(node->left_);
		return rightheight > leftheight ? (rightheight + 1) : (leftheight + 1);
	}

	inline Node<T>* getUncleNode(Node<T>* node)
	{
		assert(node);

		if (node->parent_)
		{
			if (node->parent_->left_ == node)
				return node->parent_->right_;
			else
				return node->parent_->left_;
		}

		return NULL;
	}

	inline void setColor(Node<T>* node,int color)
	{
		assert(color == RED || color == BLACK);
		if (node)
			node->color_ = color;
	}

	//将节点右旋
	Node<T>* turnRight(Node<T>* node)
	{
		// 右旋使node的父节点的子节点替换为b
		Node<T>* b = node->left_;
		if (node->parent_ != NULL) {
			if (node->parent_->right_ == node)
			{
				node->parent_->right_ = b;
			}
			else
			{
				node->parent_->left_ = b;
			}
		}
		b->parent_ = node->parent_;
		//将b的右子树作为a的左子树,并将a作为b的右子树
		node->parent_ = b;
		node->left_ = b->right_;
		if (node->left_ != NULL)
			node->left_->parent_ = node;
		b->right_ = node;
		//返回b节点
		return b;
	}

	//将节点左旋
	Node<T>* turnLeft(Node<T>* node)
	{
		//左旋把node的父节点的子节点替换为b
		Node<T>* b = node->right_;
		if (node->parent_ != NULL) {
			if (node->parent_->right_ == node) {
				node->parent_->right_ = b;
			}
			else {
				node->parent_->left_ = b;
			}
		}
		b->parent_ = node->parent_;
		//将node作为b的左子树,并将b的左子树作为node的右子树
		node->parent_ = b;
		node->right_ = b->left_;
		b->left_ = node;
		if (node->right_ != NULL)
			node->right_->parent_ = node;
		//返回b节点
		return b;
	}

	//重新平衡node节点
	void insertRebalance(Node<T>* node, Node<T>* newNode)
	{
		if (!node) return;
		if (node->color_ == BLACK) //插入节点的父节点是黑节点
		{
			//不需要处理任何行为
		}
		else if (node->color_ == RED)//插入节点的父节点是红节点,必有祖父节点
		{
			Node<T>* uncleNode = getUncleNode(node);
			if (uncleNode && uncleNode->color_ == RED) //4.1
			{
				//处理:父节点、叔叔节点设为黑色 祖父节点设为红色
				
				setColor(node, BLACK);
				setColor(uncleNode, BLACK);
				if (node->parent_ != tree_)
				{
					setColor(node->parent_, RED);
				}
				insertRebalance(node->parent_->parent_, node->parent_);
			}
			//4.2
			else if ((!uncleNode || uncleNode->color_ == BLACK) && (node->parent_ && node->parent_->left_ && node->parent_->left_ == node))
			{
				if (node->left_ == newNode) //4.2.1
				{
					//处理:父节点设为黑色 将祖父节点设为红色 将祖父节点右旋
					setColor(node, BLACK);
					setColor(node->parent_, RED);
					turnRight(node->parent_);
				}
				else if (node->right_ == newNode)//4.2.2
				{
					//处理:将父节点左旋  插入节点设为黑色 祖父节点设为红色 对祖父节点左旋
					node = turnLeft(node);
					//得到4.2.1 进行4.2.1操作
					//						setColor(newNode, BLACK);
					//						setColor(newNode->parent_, RED);
					//						newNode->parent_ = turnRight(newNode->parent_);
					insertRebalance(node->parent_, node);
				}
			}
			//4.3
			else if ((!uncleNode || uncleNode->color_ == BLACK) && (node->parent_ && node->parent_->right_ && node->parent_->right_ == node))
			{
				if (node->right_ == newNode) //4.3.1
				{
					//处理:将父节点设为黑色 将祖父节点设为红色 对祖父节点左旋
					setColor(node, BLACK);
					setColor(node->parent_, RED);
					node = turnLeft(node->parent_);

					//						rebalance(turnLeft(node->parent_));
				}
				else if (node->left_ == newNode)//4.3.2
				{
					//处理:将父节点右旋  插入节点设为黑色 祖父节点设为红色 对祖父节点左旋
					node = turnRight(node);

					//得到4.3.1 进行4.3.1 操作
					//						setColor(newNode, BLACK);
					//						setColor(node->parent_, RED);
					//						node = turnLeft(node->parent_);
					insertRebalance(node->parent_, node);
				}
			}
		}
		else
		{
			assert(false);
		}

		//往上重新平衡

		if (node->parent_)
		{
//			rebalance(node->parent_,node);
		}
		else
		{
			tree_ = node;
		}
	}

	//replaceNode 替代节点 deleteNode 删除节点
	void deleteRebalance(Node<T>* replaceNode, Node<T>* deleteNode)
	{
		if (!replaceNode && !deleteNode) return;

		if (replaceNode->color_ == RED) //情景1
		{
			deleteNode->data_ = replaceNode->data_;

		}
		else if (replaceNode->color_ == BLACK) //必有兄弟节点
		{
			if (replaceNode->parent_->left_ == replaceNode)//2.1
			{
				Node<T>* replaceBrotherNode = replaceNode->parent_->right_; //替换节点的兄弟节点
				if (replaceBrotherNode->color_ == RED)//2.1.1 //必成立
				{
					replaceBrotherNode->color_ = BLACK;
					replaceNode->parent_->color_ = RED;
					Node<T>* node = turnLeft(replaceNode->parent_);
					if (!node->parent_) tree_ = node;
					deleteRebalance(replaceNode, replaceNode);
				}
				else if (replaceBrotherNode->color_ == BLACK) //2.1.2
				{
					if (replaceBrotherNode->right_ && replaceBrotherNode->right_->color_ == RED) //2.1.2.1
					{
						replaceBrotherNode->color_ = replaceBrotherNode->parent_->color_;
						replaceBrotherNode->right_->color_ = BLACK;
						replaceBrotherNode->parent_->color_ = BLACK;
						Node<T>* node = turnLeft(replaceBrotherNode->parent_);
						if (!node->parent_) tree_ = node;
					}
					else if((replaceBrotherNode->left_ && replaceBrotherNode->left_->color_ == RED) &&
						(!replaceBrotherNode->right_ || replaceBrotherNode->right_->color_ == BLACK))//2.1.2.2
					{
						replaceBrotherNode->color_ = RED;
						replaceBrotherNode->left_->color_ = BLACK;
						Node<T>* node = turnRight(replaceBrotherNode);
						if (!node->parent_) tree_ = node;
						deleteRebalance(replaceNode, replaceNode);
					}
					else if ((!replaceBrotherNode->left_ && !replaceBrotherNode->right_) ||
						(replaceBrotherNode->left_ && replaceBrotherNode->left_->color_ == BLACK
							&& replaceBrotherNode->right_ && replaceBrotherNode->right_->color_ == BLACK))//2.1.2.3
					{
						replaceBrotherNode->color_ = RED;
//						replaceBrotherNode->parent_->color_ = BLACK;
						deleteRebalance(replaceBrotherNode->parent_, replaceBrotherNode->parent_);
					}
				}
			}
			else if (replaceNode->parent_->right_ == replaceNode) //2.2
			{
				Node<T>* replaceBrotherNode = replaceNode->parent_->left_; //替换节点的兄弟节点
				if (replaceBrotherNode->color_ == RED)//2.2.1 //必成立
				{
					replaceBrotherNode->color_ = BLACK;
					replaceNode->parent_->color_ = RED;
					Node<T>* node = turnRight(replaceNode->parent_);
					if (!node->parent_) tree_ = node;
					deleteRebalance(replaceNode, replaceNode);
				}
				else if (replaceBrotherNode->color_ == BLACK) //2.2.2
				{
					if (replaceBrotherNode->left_ && replaceBrotherNode->left_->color_ == RED) //2.2.2.1
					{
						replaceBrotherNode->color_ = replaceBrotherNode->parent_->color_;
						replaceBrotherNode->left_->color_ = BLACK;
						replaceBrotherNode->parent_->color_ = BLACK;
						Node<T>* node = turnRight(replaceBrotherNode->parent_);
						if (!node->parent_) tree_ = node;
					}
					else if ((!replaceBrotherNode->left_ || replaceBrotherNode->left_->color_ == BLACK) &&
						(replaceBrotherNode->right_ && replaceBrotherNode->right_->color_ == RED))//2.2.2.2
					{
						replaceBrotherNode->color_ = RED;
						replaceBrotherNode->right_->color_ = BLACK;
						Node<T>* node = turnLeft(replaceBrotherNode);
						if (!node->parent_) tree_ = node;
						deleteRebalance(replaceNode, replaceNode);
					}
					else if ((!replaceBrotherNode->left_ && !replaceBrotherNode->right_) ||
						(replaceBrotherNode->left_ && replaceBrotherNode->left_->color_ == BLACK
							&& replaceBrotherNode->right_ && replaceBrotherNode->right_->color_ == BLACK))//2.2.2.3
					{
						replaceBrotherNode->color_ = RED;
						replaceBrotherNode->parent_->color_ = BLACK;
						//deleteRebalance(replaceBrotherNode->parent_, replaceBrotherNode->parent_);
					}
				}
			}
		}
	}

	//插入操作
	void insert(const T& value, Node<T>* root = NULL)
	{
		if (!root) root = tree_;

		Node<T>* node = select(value, root);

		if (node == NULL) //为空 代表tree为空
		{
			tree_ = allocNode(value);
			setColor(tree_, BLACK);
		}
		else if (node->data_ == value) //更新节点
		{
			tree_->data_ = value;
		}
		else if (node->data_ != value)
		{
			Node<T>* newNode = allocNode(value);
			newNode->parent_ = node;

			if (node->data_ > value) //新增节点比跟节点小 则查到根节点的左节点上
			{
				node->left_ = newNode;
			}
			else if (node->data_ < value)//新增节点比跟节点大 则查到根节点的右节点上
			{
				node->right_ = newNode;
			}

			insertRebalance(node,newNode);
		}
	}



	//查询操作 递归查询 未找到返回可以插入的根节点
	//const T& value 要查询的value
	//Node<T>* root 从哪个根节点开始查询 默认从根节点开始
	Node<T>* select(const T& value, Node<T>* root = NULL)
	{
		if (!root) root = tree_;

		if (!root) return NULL;

		if (root->data_ == value) //找到该节点
			return root;
		else if (root->data_ > value) //
		{
			if (root->left_)
				return select(value, root->left_); //继续到左子节点查询
			else
				return root; //返回根节点
		}
		else if (root->data_ < value)
		{
			if (root->right_)
				return select(value, root->right_); //继续到右子节点查询
			else
				return root;//返回根节点
		}

		return NULL;
	}

	//获取该根节点上最小的节点
	inline Node<T>* getmin(Node<T>* node)
	{
		if (node->left_)
			getmin(node->left_);
		else
			return node;
	}

	//删除节点  当该节点只有一个子节点或没有子节点
	void delnodeifhas1childornot(Node<T>* node)
	{
		if (!node) return;
		if (node->parent_ == NULL) //是根节点
		{
			tree_ = node->left_ ? node->left_ : node->right_;
			tree_->parent_ = NULL;
		}
		else
		{
			Node<T>* childNode = node->left_ ? node->left_ : node->right_;

			if (childNode)//有孩子节点
			{
				assert(childNode->color_ == RED); //该孩子节点颜色必是红色 那么node 必是黑色
				assert(node->color_ == BLACK);
				childNode->parent_ = node->parent_;
				childNode->color_ = BLACK;
			}
			else //如果没有孩子节点 
			{
				if (node->color_ == BLACK) //删除节点是黑色 需要自平衡
				{
					deleteRebalance(node, node);
				}
			}

			if (node->parent_->left_ == node)
			{
				node->parent_->left_ = childNode;
			}
			else
			{
				node->parent_->right_ = childNode;
			}

//			rebalance(node->parent_);
		}
		delete node;
		node = NULL;
	}

	void delnodeifhas2child(Node<T>* node)
	{
		Node<T>* after = getmin(node->right_);
		node->data_ = after->data_;
		delnodeifhas1childornot(after);
	}

	void del(const T& value)
	{
		Node<T>* node = select(value, tree_);
		if (node->data_ == value)
		{
			if (node->left_ && node->right_) 
			{
				delnodeifhas2child(node);
			}
			else
			{
				delnodeifhas1childornot(node);
			}
		}
	}


	//先序遍历
	void preOrderTraverse(Node<T> *root = NULL)
	{
//		if (!root) root = tree_;
		if (root)
		{
			printf("%d  ", root->data_);
			preOrderTraverse(root->left_);
			preOrderTraverse(root->right_);
		}
	}

	//中序遍历
	void midOrderTraverse(Node<T> *root = NULL)
	{
		if (root)
		{
			midOrderTraverse(root->left_);
			printf("%d  ", root->data_);
			midOrderTraverse(root->right_);
		}
	}

	//后序遍历
	void postOrderTraverse(Node<T> *root = NULL)
	{
		if (!root) root = tree_;
		if (root)
		{
			postOrderTraverse(root->left_);
			postOrderTraverse(root->right_);
			printf("%d  ", root->data_);
		}
	}

	Node<T>* getTree()
	{
		return tree_;
	}

private:
	Node<T>* tree_;  //AVL tree的树根
//	int count_;  //节点数

};

int main()
{
	{
		RBTree<int> rb;
		rb.insert(3);
		rb.insert(4);
		rb.insert(5);
		rb.insert(6);
		rb.insert(7);
		rb.insert(8);
		rb.insert(9);
		rb.insert(10);
		rb.insert(11);
		rb.insert(12);
		rb.insert(13);
		rb.del(3);
		rb.preOrderTraverse(rb.getTree());
		cout << endl;
		rb.midOrderTraverse(rb.getTree());
	}

	system("pause");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值