0
点赞
收藏
分享

微信扫一扫

【进阶OpenCV】 (6)--指纹识别

花姐的职场人生 2024-10-08 阅读 17
数据结构

目录

一、认识红黑树:

1、红黑树概念:

2、红黑树的性质:

3、红黑树节点的定义:

二、红黑树的插入:

1、插入注意事项:

2、插入理解:

三、红黑树的检查:

四、红黑树和AVL树的比较:


一、认识红黑树:

1、红黑树概念:

接下来看看红黑树的全貌:

2、红黑树的性质:

如下图所示:

最长路径:红黑相间的路径

最短路径:全是黑节点的路径

3、红黑树节点的定义:

enum COLOR
{
	RED,
	BLACK
};

template<class K, class V>
struct RBTreeNode
{
	RBTreeNode<K, V>* _left;
	RBTreeNode<K, V>* _right;
	RBTreeNode<K, V>* _parent;
	pair<K, V> _kv;
	COLOR col;

	RBTreeNode(const pair<K, V>& kv)
		:_left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, col(RED)
	{}
};

二、红黑树的插入:

1、插入注意事项:

2、插入理解:

情况一:当新插入节点的uncle存在,且是红节点

对应的抽象图:

情况二:当新插入节点的uncle不存在

当uncle存在且为黑:

                        在上述中判断是单旋或者双旋是通过指针的指向来判断的

bool Insert(pair<K, V> kv)
{
	//先进来判断这个树是不是空树
	if (_root == nullptr)
	{
		_root = new Node(kv);
		_root->col = BLACK;
		return true;
	}
	Node* parent = nullptr;
	Node* cur = _root;
	//找到要插入的位置
	while (cur)
	{
		if (cur->_kv.first > kv.first)
		{
			parent = cur;
			cur = cur->_left;
		}
		else if (cur->_kv.first < kv.first)
		{
			parent = cur;
			cur = cur->_right;
		}
		else
		{
			return false;
		}
	}
	//走到这就是找到了
	cur = new Node(kv);
	cur->col = RED;
	//再连接到这个红黑树中
	if (parent->_kv.first > cur->_kv.first)
	{
		parent->_left = cur;
	}
	else//parent->_kv.first < cur->_kv.first
	{
		parent->_right = cur;
	}
	cur->_parent = parent;
	//已经连接完成后
	while (parent && parent->col == RED)
	{
		//这里祖父必定存在,因为如果进循环后parent就是red,然而red不可能为根节点,所以parent的parent必定存在
		Node* grandfather = parent->_parent;
		if (parent == grandfather->_left)
		{
			Node* uncle = grandfather->_right;
			if (uncle && uncle->col == RED)
			{
				//修改颜色
				uncle->col = BLACK;
				parent->col = BLACK;
				grandfather->col = RED;
				//修改cur
				cur = grandfather;
				//修改parent继续指向cur的parent
				parent = cur->_parent;
			}
			else//uncle不存在或者uncle为黑色就需要旋转了
			{
				if (cur == parent->_left)
				{
					RotateR(grandfather);
					parent->col = BLACK;
					grandfather->col = RED;
				}
				else//cur == parent->_right
				{
					RotateL(parent);
					RotateR(grandfather);
					cur->col = BLACK;
					grandfather->col = RED;
				}
				break;
			}
		}
		else//parent == grandfather->_right
		{
			Node* uncle = grandfather->_left;
			if (uncle && uncle->col == RED)
			{
				//修改颜色
				uncle->col = BLACK;
				parent->col = BLACK;
				grandfather->col = RED;
				//修改cur
				cur = grandfather;
				//修改parent继续指向cur的parent
				parent = cur->_parent;
			}
			else//uncle不存在或者uncle为黑色就需要旋转了
			{
				if (cur == parent->_right)
				{
					RotateL(grandfather);
					parent->col = BLACK;
					grandfather->col = RED;
				}
				else//cur == parent->_right
				{
					RotateR(parent);
					RotateL(grandfather);
					cur->col = BLACK;
					grandfather->col = RED;
				}
				break;
			}
		}
	}
	_root->col = BLACK;
	return true;
}
	//左单旋
	void RotateL(Node* parent)
	{
		Node* cur = parent->_right;
		Node* curleft = cur->_left;

		parent->_right = curleft;
		if (curleft)
		{
			curleft->_parent = parent;
		}
		cur->_left = parent;

		//将parent的父节点保存起来
		Node* pparent = parent->_parent;
		parent->_parent = cur;

		if (parent == _root)
		{
			_root = cur;
			cur->_parent = nullptr;
		}
		else
		{
			if (pparent->_kv.first < cur->_kv.first)
			{
				pparent->_right = cur;
			}
			else //if (pparent->_kv.first > cur->_kv.first)
			{
				pparent->_left = cur;
			}
			cur->_parent = pparent;
		}
	}

	//右单旋
	void RotateR(Node* parent)
	{
		Node* cur = parent->_left;
		Node* curright = cur->_right;

		parent->_left = curright;
		if (curright)
		{
			curright->_parent = parent;
		}
		cur->_right = parent;

		//将parent的父节点保存起来
		Node* pparent = parent->_parent;
		parent->_parent = cur;

		if (parent == _root)
		{
			_root = cur;
			cur->_parent = nullptr;
		}
		else
		{
			if (pparent->_kv.first < cur->_kv.first)
			{
				pparent->_right = cur;
			}
			else //if (pparent->_kv.first > cur->_kv.first)
			{
				pparent->_left = cur;
			}
			cur->_parent = pparent;
		}
	}

三、红黑树的检查:

性质三检查:

性质四检查:

bool CheckColor(Node* root, int blacknum, int benchmark)
{
	if (root == nullptr)
	{
		if (blacknum != benchmark)
		{
			cout << "黑色节点的数量不匹配" << endl;
			return false;
		}
		return true;
	}
	if (root->col == BLACK)
	{
		++blacknum;
	}

	if (root->col == RED && root->_parent && root->_parent->col == RED)
	{
		cout << root->_kv.first << "出现连续红色节点" << endl;
		return false;
	}
	return CheckColor(root->_left, blacknum, benchmark)
		&& CheckColor(root->_right, blacknum, benchmark);
}

bool IsRBTree()
{
	return _IsRBTree(_root);
}

bool _IsRBTree(Node* root)
{
	if (root == nullptr)
		return true;
	if (root->col == RED)
	{
		return false;
	}

	//基准值
	int benchmark = 0;
	Node* cur = _root;
	while (cur)
	{
		if (cur->col == BLACK)
			++benchmark;
		cur = cur->_left;
	}
	return CheckColor(root, 0, benchmark);
}

四、红黑树和AVL树的比较:

举报

相关推荐

0 条评论