红黑树/红黑树迭代器封装(C++)

        本篇将会较为全面的讲解有关红黑树的特点,插入操作,然后使用代码模拟实现红黑树,同时还会封装出红黑树的迭代器。

        在 STL 库中的 set 和 map 都是使用红黑树封装的,在前文中我们讲解了 AVL树,对于红黑树和 AVL 树来说,这两种树都是效率很高的搜索二叉树,但是相对而言 AVL 树会更加接近平衡二叉树,但是用于封装 set 和 map 的却是红黑树,这是因为虽然红黑树不是很接近平衡二叉树,但是和 AVL 树的搜索效率相比较其实相差不是很多,相反而言,对于红黑树在插入时的效率会比 AVL 树更高,所以封装 set 和 map 选择使用了红黑树。

        如下:

目录

1. 红黑树

All code

红黑树的特性

红黑树节点的定义

红黑树的插入操作

红黑树检测与暴力测试

2. 红黑树迭代器封装

 迭代器的测试

1. 红黑树

All code

#pragma once
#include 
#include 
#include 
using namespace std;

enum Colour { RED, BLACK };

// 节点
template 
struct BRTreeNode {
	BRTreeNode* _left;
	BRTreeNode* _right;
	BRTreeNode* _parent;
	pair _kv;
	Colour _col;

	BRTreeNode(const pair& kv)
		: _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _kv(kv)
		, _col(RED)
	{}
};

// k v
template 
class Iterator {
	typedef Iterator Self;
	typedef BRTreeNode Node;
	typedef pair& Ref;
	typedef pair* Ptr;
public:
	Iterator(Node* node)
		:_node(node)
	{}

	Ref operator*() {
		return _node->_kv;
	}

	Ptr operator->() {
		return &(_node->_kv);
	}

	Self operator++() {
		// left middle right
		// 如果有右孩子节点,找出右孩子节点中的最左节点
		// 如果没有右孩子节点,需要不断向上迭代,找到最左节点
		if (_node->_right != nullptr) {
			Node* leftMin = _node->_right;
			while (leftMin && leftMin->_left) {
				leftMin = leftMin->_left;
			}
			_node = leftMin;
		}
		else {
			Node* parent = _node->_parent;
			Node* cur = _node;
			while (parent && cur != parent->_left) {
				cur = parent;
				parent = cur->_parent;
			}
			_node = parent;
		}
		return *this;
	}

	Self operator--() {
		// 若当前迭代器为null,返回最右节点
		// left middle right
		// 如果有左孩子,找出左孩子中的最大节点
		// 如果没有左孩子,需要向上迭代


		if (_node->_left != nullptr) {
			Node* rightMin = _node->_left;
			while (rightMin && rightMin->_right) {
				rightMin = rightMin->_right;
			}
			_node = rightMin;
		}
		else {
			Node* parent = _node->_parent;
			Node* cur = _node;
			while (parent && cur != parent->_right) {
				cur = parent;
				parent = cur->_parent;
			}
			_node = parent;
		}
		return *this;
	}

	bool operator!=(const Self& it) {
		return _node != it._node;
	}

private:
	Node* _node;
};

template 
class BRTree {
	typedef BRTreeNode Node;
public:
	typedef Iterator iterator;
	// 封装迭代器
	iterator begin() {
		// 找到最左节点
		Node* leftMin = _root;
		while (leftMin && leftMin->_left) {
			leftMin = leftMin->_left;
		}
		return iterator(leftMin);
	}

	iterator end() {
		return iterator(nullptr);
	}
	// 插入
	bool insert(const pair& kv) {
		if (_root == nullptr) {
			_root = new Node(kv);
			_root->_col = BLACK;
			return true;
		}
		Node* cur = _root;
		Node* parent = nullptr;
		while (cur) {
			if (kv.first < cur->_kv.first) {
				parent = cur;
				cur = cur->_left;
			}
			else if (kv.first > cur->_kv.first) {
				parent = cur;
				cur = cur->_right;
			}
			else {
				// 遇见相同元素
				return false;
			}
		}
		cur = new Node(kv);
		if (parent->_kv.first < cur->_kv.first)
			parent->_right = cur;
		else
			parent->_left = cur;
		cur->_parent = parent;
		// 开始调整
		while (parent && parent->_col == RED) {
			Node* grandfather = parent->_parent;
			// 先判断当前插入的节点是在爷爷节点的左边还是右边
			if (parent == grandfather->_left) {
				Node* uncle = grandfather->_right;
				// 一共存在两种情况,叔叔节点存在且叔叔节点不为黑色
				if (uncle && uncle->_col == RED) {
					parent->_col = BLACK;
					uncle->_col = BLACK;
					grandfather->_col = RED;
					// 更新
					cur = grandfather;
					parent = cur->_parent;
				}
				else {
					// 现在这种情况属于叔叔节点不存在或者存在为黑
					// 需要判断当前属于什么情况
					if (cur == parent->_left) {
						//      g           p
						//   p     u -->  c   g
						// c                    u
						// 右旋即可
						RotateRight(grandfather);
						parent->_col = BLACK;
						cur->_col = grandfather->_col = RED;
					}
					else {
						//      g            g          c
						//   p     u -->   c   u -->  p   g
						//     c         p                   u
						// 先左旋,后右旋
						RotateLeft(parent);
						RotateRight(grandfather);
			

你可能感兴趣的:(Cpp,数据结构,数据结构,C++,红黑树,迭代器)