【手撕红黑树】

二叉搜索树

作为一种二叉树类型的数据结构,掌握期性质是首要.

总的说就是,以某结点为视角,其左子树均为小于该结点值的结点,而右子树相反,且无重复值的结点.

 性质:去重性,有序性.

自主实现

 构造逻辑:但凡实现某功能,作为程序员,既要站在底层的角度,也要多从用户角度去考虑;

这是个二叉树数据结构,对其访问,用户仅需声明对应的类,然后调用对应的功能接口,

那我们就应这样思考,首先这主角对象应构建出来,即对结点进行创建,他包含什么成员变量,可以或应该提供什么接口,在这仅需描述出具体对象即可,接口不需要

接下来是对是操作方面的构建,对着结点,以怎样的数据结构管理,因该或可以提供什么接口,

这是对操作的封装,站在用户角度更佳.

对一个任务的具体分析,在分解至较小步骤,这样不至于不知怎么着手

1.单值数据成员

 明确结构:1.一个含模板Node类描述结点,包括成员变量指针,数据成员,构造函数初始化;

2.一个BinarySearchTree类,提供二叉搜索树的功能接口,插入,删除,查找,判断(可补充 求高度,结点个数);

知识点:对链表的结点操作(增删查改),指针运用,递归的运用(前,中序遍历,如何通过递归返回需求值).体会类和对象的封装性,面相对象.

收获:为什么递归要封装一层函数(提供给用户接口,封装性),搜索树的拷贝需要深拷贝,

BSTree() =default;禁止生成默认构造函数-为什么,有什么意义:a.强制初始化,b.避免产生无意义的对象,c.强制采用特定的构造方式. 本例子中,创造没有根结点的二叉树是无意义的

2.双值数据成员

目的:为后续键值对数据类型的学习做铺垫

大致内容相似,就数据成员的改动.

3.实现代码

#pragma once

#include<iostream>
#include<cassert>
//命名空间
namespace key
{
    //结点的构建
	template<class K>
	struct BSTreeNode
	{

		typedef BSTreeNode<K> Node;
		Node* _left;
		Node* _right;
		K _key;
		BSTreeNode(const K key)
			:_left(nullptr), _right(nullptr), _key(key)
		{

		}
	};



    //二叉搜索树的接口实现--因为提供给用户,无法访问私有成员,所以在需要根节点是,封装一层函数
	template<class K>
	class BSTree
	{
		typedef BSTreeNode<K> Node;
	public:
		BSTree() =default;

		BSTree(const BSTree<K>& t)
		{
			_root = Copy(t._root);//?
		}

		void swap(Node* &p1, Node* &p2)
		{
			
			p1 = deepCopyTree(p2);
		}
		BSTree <K>& operator=( BSTree<K> &t)
		{
			swap(_root,t._root);
			return *this;
		}
		~BSTree()
		{
			Destroy(_root);
		}
		bool Find(const K key)
		{
			if (nullptr == _root)
			{
				return false;
			}
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (key < cur->_key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (key > cur->_key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					return true;
				}
			}
			return false;
		}
		bool Insert(const K key)
		{
			if (nullptr == _root)
			{
				//Node newNode = new Node(key);
				//_root = &newNode;
				_root = new Node(key);
				return true;
			}
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (key < cur->_key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (key > cur->_key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					return false;
				}
			}
			cur = new Node(key);
			if (key < parent->_key)
			{
				parent->_left = cur;;
			}
			else
			{
				parent->_right = cur;
			}
			return true;
		}
		bool Erase(const K key)
		{
			if (nullptr == _root)
			{
				return false;
			}
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (key < cur->_key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (key > cur->_key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					if (cur == _root)
					{
						delete cur;
						_root = nullptr;
					}
					if (cur->_left == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_right;
							delete cur;
							return true;
						}
						if (cur == parent->_left)
						{
							parent->_left = cur->_right;
						}
						else
						{
							parent->_right = cur->_right;
						}
						delete cur;
						return true;
					}
					else if (cur->_right == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_left;
							delete cur;
							return true;
						}
						if (cur == parent->_left)
						{
							parent->_left = cur->_left;
						}
						else
						{
							parent->_right = cur->_left;
						}
						delete cur;

						return true;

					}
					else
					{
						Node* LeftMaxParent = cur;
						Node* LeftMax = cur->_left;
						while (LeftMax->_right)
						{
							LeftMaxParent = LeftMax;
							LeftMax = LeftMax->_right;
						}
						cur->_key = LeftMax->_key;
						if (LeftMax == LeftMaxParent->_left)
						{
							LeftMaxParent->_left = LeftMax->_left;
						}
						else
						{
							LeftMaxParent->_right = LeftMax->_left;
						}
						delete LeftMax;
						return true;
					}
				}
			}
			return false;
			
		}
		void Inorder()
		{			
			return _Inorder(this->_root);

		}
/*---------------------------------------------------------*/
		bool FindR(const K& key)
		{
			return _FindR(_root,key);
		}

		bool InsertR(const K& key)
		{
			return _InsertR(_root, key);
		}

		bool EraseR(const K& key)
		{
			return _EraseR(_root, key);
		}

	private:
			bool _FindR(Node* root, const K& key)
			{
				if (root == nullptr)
				{
					return false;
				}
				if (key < root->_key)
				{
					return _FindR(root->_left,key);
				}
				else if (key > root->_key)
				{
					return _FindR(root->_right, key);
				}
				else
				{
					return true;
				}
			}

			bool _InsertR(Node*& root, const K& key)
			{
				if (root == nullptr)
				{
					root = new Node(key);
					return true;
				}
				if (key < root->_key)
				{
					return _InsertR(root->_left, key);
				}
				else if (key > root->_key)
				{
					return _InsertR(root->_right, key);
				}
				else
				{
					return false;
				}
			}

			bool _EraseR(Node*& root, const K& key)
			{
				if (root == nullptr)
				{
					return false;
				}
				if (key < root->_key)
				{
					return _EraseR(root->_left, key);
				}
				else if (key > root->_key)
				{
					return _EraseR(root->_right, key);
				}
				else
				{
					if (root->_left == nullptr)
					{
						Node* tmp = root;
						root = root->_right;
						delete tmp;
						return true;
					}
					else if (root->_right == nullptr)
					{
						Node* tmp = root;
						root = root->_left;
						delete tmp;
						return true;
					}
					else
					{
						Node* LeftMaxParent = root;
						Node* LeftMax = root->_left;
						while (LeftMax->_right)
						{
							LeftMaxParent = LeftMax;
							LeftMax = LeftMax->_right;
						}
						root->_key = LeftMax->_key;
						if (LeftMax == LeftMaxParent->_left)
						{
							LeftMaxParent->_left = LeftMax->_left;
						}
						else
						{
							LeftMaxParent->_right = LeftMax->_left;
						}
						delete LeftMax;
						return true;
					}
				}
			}
	private:
		Node* deepCopyTree(const Node* root) {
			if (root == nullptr) {
				return nullptr;
			}

			// 创建当前节点的拷贝
			Node* newNode = new Node(root->_key);

			// 递归拷贝左子树和右子树
			newNode->_left = deepCopyTree(root->_left);
			newNode->_right = deepCopyTree(root->_right);

			return newNode;
		}
		void Destroy(const Node* root)
		{
			if (root == nullptr) return;
			Destroy(root->_left);
			Destroy(root->_right);
			delete root;
		}
		Node* Copy(const Node* root)
		{
			/*Node* newRoot = new Node(root->_key);
			newRoot->_left = root->_left;
			newRoot->_right = root->_right;
			return newRoot;*/
			return deepCopyTree(root);
		}
		void _Inorder(const Node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			_Inorder(root->_left);
			std::cout << root->_key << " ";
			_Inorder(root->_right);
		}
	private:
		Node* _root = nullptr;
	};
}


//体会双值的区别,为键值对做铺垫
namespace key_value
{
	template<class K,class V>
	struct BSTreeNode
	{

		typedef BSTreeNode<K,V> Node;
		Node* _left;
		Node* _right;
		K _key;
		V _value;
		BSTreeNode(const K key,const V value)
			:_left(nullptr), _right(nullptr), _key(key), _value(value)
		{

		}
	};
	template<class K,class V>
	class BSTree
	{
		typedef  BSTreeNode<K,V> Node;
	public:
		bool Find(const K key)
		{
			if (nullptr == _root)
			{
				return false;
			}
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (key < cur->_key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (key > cur->_key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					return true;
				}
			}
			return false;
		}
		bool Insert(const K key,const V value)
		{
			if (nullptr == _root)
			{
				//Node newNode = new Node(key);
				//_root = &newNode;
				_root = new Node(key, value);
				return true;
			}
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (key < cur->_key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (key > cur->_key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					return false;
				}
			}
			cur = new Node(key, value);
			if (key < parent->_key)
			{
				parent->_left = cur;;
			}
			else
			{
				parent->_right = cur;
			}
			return true;
		}
		bool Erase(const K key)
		{
			if (nullptr == _root)
			{
				return false;
			}
			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (key < cur->_key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else if (key > cur->_key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else
				{
					if (cur == _root)
					{
						delete cur;
						_root = nullptr;
					}
					if (cur->_left == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_right;
							delete cur;
							return true;
						}
						if (cur == parent->_left)
						{
							parent->_left = cur->_right;
						}
						else
						{
							parent->_right = cur->_right;
						}
						delete cur;
						return true;
					}
					else if (cur->_right == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_left;
							delete cur;
							return true;
						}
						if (cur == parent->_left)
						{
							parent->_left = cur->_left;
						}
						else
						{
							parent->_right = cur->_left;
						}
						delete cur;

						return true;

					}
					else
					{
						Node* LeftMaxParent = cur;
						Node* LeftMax = cur->_left;
						while (LeftMax->_right)
						{
							LeftMaxParent = LeftMax;
							LeftMax = LeftMax->_right;
						}
						cur->_key = LeftMax->_key;
						if (LeftMax == LeftMaxParent->_left)
						{
							LeftMaxParent->_left = LeftMax->_left;
						}
						else
						{
							LeftMaxParent->_right = LeftMax->_left;
						}
						delete LeftMax;
						return true;
					}
				}
			}
			return false;

		}
		void Inorder()
		{
			return _InOrder(this->_root);
			std::cout << std::endl;
		}
		private:
			void _InOrder(Node* root)
			{
				if (root == nullptr)
					return;

				_InOrder(root->_left);
				std::cout << root->_key << " "<<root->_value<<" "<<std::endl;
				_InOrder(root->_right);
			}
		private:
			Node* _root = nullptr;
	};
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值