红黑树C++

红黑树定义:

1、每个结点要么是红的,要么是黑的

2、根结点是黑的

3、每个叶结点,即空节点是黑的

4、如果一个结点是红的,则它的两个儿子是黑的

5、对每个结点,从该结点到其子算结点的所有路径上包含相同数目的黑结点。


红黑树性质:

1、一棵有n个内结点的红黑树的高度至多为2lg(n+1)

2、RB-insert总共花费为O(lgn)时间,最多执行旋转次数为2次

3、RB-delete-fixup要花O(lgn)时间,最多做三次旋转。


这段代码有bug,贴出来希望同胞们帮忙指正 不知道到底是哪错了!调了好久了还没调出来 伤心,泪奔!大哭

谢谢了!!!


#include <iostream>
using namespace std;

class rbTree
{
private:
	typedef bool rbTree_color_type;
	const rbTree_color_type rbTree_red;
	const rbTree_color_type rbTree_black;

	//结点结构
	struct rbNode  
	{
		rbNode *parent;
		rbNode *left;
		rbNode *right;
		int data;
		rbTree_color_type color;    //颜色
		rbNode() : parent(NULL), left(NULL), right(NULL), data(-1), color(true)
		{

		}
	};
	rbNode *root;
	rbNode *sentry; //哨兵结点,代表空结点

public:
	rbTree() : sentry(new rbNode), rbTree_red(false), rbTree_black(true)
	{
		root = sentry;
	}

	void createRbTree()
	{
		int val;
		while (cin >> val)
			rbInsert(val);
	}

	//中序遍历二叉树
	void traverse()
	{
		__traverse(root);
	}

	rbNode* treeMiniNum()
	{
		if (root == sentry)
		{
			cout << "树为空!" << endl;
			return sentry;
		}
		while (root != sentry)
			root = root->left;
		return root;
	}

	int treeMiniNum1()
	{
		if (root == sentry)
		{
			cout << "树为空!" << endl;
			return -1;
		}
		while (root != sentry)
			root = root->left;
		return root->data;
	}

	rbNode* treeMaxiNum()
	{
		if (root == sentry)
		{
			cout << "树为空!" << endl;
			return sentry;
		}
		while (root != sentry)
			root = root->right;
		return root;
	}

	int treeMaxiNum1()
	{
		if (root == sentry)
		{
			cout << "树为空!" << endl;
			return -1;
		}
		while (root != sentry)
			root = root->right;
		return root->data;
	}

	//查找前驱,与查找后继相对应
	rbNode* rbTreePreDecessor(rbNode* node)
	{
		if (node->left != sentry)
		{
			rbNode *tmpNode = node->left;
			while (tmpNode->right != sentry)
				tmpNode = tmpNode->right;
			return tmpNode;
		}
		rbNode *pNode = node->parent;
		while (pNode != sentry && node != pNode->right)
		{
			node = pNode;
			pNode = pNode->parent;
		}
		return pNode;
	}

	//查找后继
	rbNode* rbTreeSuccessor(rbNode* node)
	{	
		if (node->right != sentry)
		{
			rbNode *tmpNode = node->right;
			while (tmpNode->left != sentry)
				tmpNode = tmpNode->left;
			return tmpNode;
		}
		rbNode *pNode = node->parent;
		while (pNode != sentry && node != pNode->left)
		{
			node = pNode;
			pNode = pNode->parent;
		}
		return pNode;	
	}	

	rbNode *rbSearch(int val)
	{
		if (root == sentry)
		    return root;
		else
		{
			rbNode *node = root;
			while (node != sentry && val != node->data)
			{
               if (val < node->data)
                  node = node->left;
			   else 
                  node = node->right;
			}
			return node;
		}
	}

	//红黑树插入
	void rbInsert(int val)
	{
		return __rbInsert(root, val);
	}

	//红黑树删除
	rbNode* rbDelete(rbNode *&node)
	{
		return __rbDelete(node);
	}

private:
	void __traverse(rbNode *root)
	{
        if (root == sentry)
           return;
		__traverse(root->left);
		cout << root->data << " ";
		__traverse(root->right);
	}

	void leftRotate(rbNode *&x)
	{
		if (x == sentry || x->right == sentry)
			return;
		rbNode *y = x->right;     //设置y
		x->right = y->left;       //y的左孩子变为x的右孩子
		if (y->left != sentry)    //如果y的左孩子不为NIL,
			y->left->parent = x;  //则设置左孩子的根节点为x
		y->parent = x->parent;    //y成为x的父节点
		if (x->parent == sentry)  //如果x的父节点为NIL
			root = y;             //y设为根结点
		else if (x == x->parent->left)
			x->parent->left = y;
		else
			x->parent->right = y;
		y->left = x;
		x->parent = y;
	}

	void rightRotate(rbNode *&y)
	{
		if (y == sentry || y->left == sentry)
			return;
		rbNode *x = y->left;
		y->left = x->right;
		if (x->right != sentry)
			x->right->parent = y;
		x->parent = y->parent;
		if (y->parent == sentry)
			root = x;
		else if (y->parent->right == y)
			y->parent->right = x;
		else
			y->parent->left = x;	
		y->parent = x;
		x->right = y;
		
	}

	void __rbInsert(rbNode *&root, int val)
	{
		rbNode *p = sentry;
		rbNode *node = root;

		rbNode *newNode = new rbNode;
		newNode->data = val;
		newNode->color = rbTree_red;
		newNode->left = sentry;
		newNode->right = sentry;
		newNode->parent = sentry;

		while (node != sentry && val != node->data)
		{
			p = node;
			if (val < node->data)
				node = node->left;
			else
				node = node->right;
		}
		node = newNode;
		node->parent = p;
		if (p == sentry)
		    root = node;
		else
		{
			if (val < p->data)
			    p->left = node;
		    else
			    p->right = node;
		}
		__rbInsertFixUp(node);
	}

	//插入之后调整使其符合红黑树的性质
	void __rbInsertFixUp(rbNode *node)
	{
		while (node->parent->color == rbTree_red)
		{
			rbNode *pNode = node->parent;
			rbNode *ppNode = pNode->parent;
			//父节点是祖父结点的左孩子
			if (ppNode->left == pNode)
			{
				rbNode *uncleNode = ppNode->right;
				//case1: 叔叔结点是红色的,需要改变颜色, 
				if (uncleNode->color == rbTree_red)
				{
					ppNode->color = rbTree_red;
					pNode->color = rbTree_black;
					uncleNode->color = rbTree_black;
					node = ppNode;
				}        			
				//case2、case3:叔叔结点是黑色的
				else 
				{
					//case2:该结点是父亲的右结点,转为case3
					if (node == pNode->right)
					{
						node = pNode;
						leftRotate(node);			
					}
					//case3:该结点是父亲的左结点
					node->parent->color = rbTree_black;
					node->parent->parent->color = rbTree_red;
					rightRotate(node->parent->parent);		
					
				}						
			}
			//父节点是祖父结点的又孩子
			else
			{
				rbNode *uncleNode = ppNode->left;
				//case4: 叔叔结点是红色的,需要改变颜色, 
				if (uncleNode->color == rbTree_red)
				{
					ppNode->color = rbTree_red;
					pNode->color = rbTree_black;
					uncleNode->color = rbTree_black;
					node = ppNode;
				}        			
				//case5、case6:叔叔结点是黑色的
				else 
				{
					//case2:该结点是父亲的右结点,转为case3
					if (node == pNode->left)
					{
						node = pNode;
						rightRotate(node);			
					}
				    //case3:该结点是父亲的左结点
					node->parent->color = rbTree_black;
					node->parent->parent->color = rbTree_red;
					leftRotate(node->parent->parent);					
				}			
			}
		}
		//保证父结点是黑色的
		root->color = rbTree_black;
	}

	rbNode* __rbDelete(rbNode* &node)
	{
		rbNode *delNode = node;
		if (node->left != sentry | node->right != sentry)
			delNode = node;
		else
			delNode = rbTreeSuccessor(node);
		rbNode *delNodeChild;
		if (delNode->left != sentry)
			delNodeChild = delNode->left;
		else
			delNodeChild = delNode->right;
		delNodeChild->parent = delNode->parent;
		if (delNode->parent == sentry)
			root = delNodeChild;
		else if (delNode == delNode->parent->left)
			delNode->parent->left = delNodeChild;
		else
			delNode->parent->right = delNodeChild;
		if (delNode != node)
		{
			node->data = delNode->data;
			node->color = delNode->color;
		}
		if (delNode->color == rbTree_black)
			__rbDeleteFixUp(delNode);
		return delNode;
	}

	void __rbDeleteFixUp(rbNode *node)
	{
		while (node != root && node->color == rbTree_black)
		{
			rbNode *pnode = node->parent;
			//结点为父结点的左孩子
			if (node == pnode->left)
			{
				rbNode *uncleNode = pnode->right;
				//case1: 结点的兄弟结点为红色
				if (uncleNode->color == rbTree_red)
				{
					uncleNode->color = rbTree_black;
					pnode->color = rbTree_red;
					leftRotate(pnode);
					uncleNode = uncleNode->left;
				}
				//case2、case3、case4: 结点的兄弟结点是黑色的
				else if (uncleNode->color == rbTree_black)
				{
					//case2: 叔叔结点的左孩子、右孩子都是黑色的,进行循环
					if (uncleNode->left->color == rbTree_black &&
						uncleNode->right->color == rbTree_black)
					{
						uncleNode->color = rbTree_red;
						node = pnode;
					}
					//case3: 叔叔结点的左孩子是红色的,右孩子是黑色的,转为case4
					else if (uncleNode->right->color == rbTree_black)
					{
						uncleNode->color = rbTree_red;
						uncleNode->left->color = rbTree_black;
						rightRotate(uncleNode);
					}
					//case4: 叔叔结点的左孩子是黑色的,右孩子是红色的
					pnode->color = rbTree_black;
					uncleNode->color = rbTree_red;
					uncleNode->right->color = rbTree_black;
					leftRotate(pnode);
				}
			}
			else
			{
				rbNode *uncleNode = pnode->left;
				//case1: 结点的兄弟结点为红色
				if (uncleNode->color == rbTree_red)
				{
					uncleNode->color = rbTree_black;
					pnode->color = rbTree_red;
					leftRotate(pnode);
					uncleNode = uncleNode->right;
				}
				//case2、case3、case4: 结点的兄弟结点是黑色的
				else if (uncleNode->color == rbTree_black)
				{
					//case2: 叔叔结点的左孩子、右孩子都是黑色的,进行循环
					if (uncleNode->left->color == rbTree_black &&
						uncleNode->right->color == rbTree_black)
					{
						uncleNode->color = rbTree_red;
						node = pnode;
					}
					//case3: 叔叔结点的左孩子是红色的,右孩子是黑色的,转为case4
					else if (uncleNode->left->color == rbTree_black)
					{
						uncleNode->color = rbTree_red;
						uncleNode->right->color = rbTree_black;
						leftRotate(uncleNode);
					}
					//case4: 叔叔结点的左孩子是黑色的,右孩子是红色的
					pnode->color = rbTree_black;
					uncleNode->color = rbTree_red;
					uncleNode->left->color = rbTree_black;
					rightRotate(pnode);
				}
			}
		}
		node->color = rbTree_black;
	}
};

int main()
{
	rbTree rbtree;
	rbtree.createRbTree();
	rbtree.traverse();
	cout << endl;

	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值