C++搜索二叉树的实现

搜索二叉树的实现

key

cpp 复制代码
namespace key{
template<class k>
struct BSTreeNode
{
	BSTreeNode<k>* _left;
	BSTreeNode<k>* _right;
	k _key;

	BSTreeNode(const k& key)
		:_left(nullptr)
		,_right(nullptr)
		,_key(key)
	{}

};


template <class k>
class BSTree {
	typedef BSTreeNode<k> Node;
private:
	Node* _root = nullptr;
public:
	BSTree() = default;

	BSTree(const BSTree<k>& t) {
		_root = Copy(t._root);
	}

	BSTree<k>& operator=(BSTree<k>& t) {
		swap(_root, t._root);
		return *this;
	}

	~BSTree() {
		Destroy(_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);
	}

	bool Insert(const k& key) {
		if (_root == nullptr) {
			_root = new BSTreeNode<k>(key);
			return true;
		}
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur) {
			if (cur->_key < key) {
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key > key) {
				parent = cur;
				cur = cur->_left;
			}
			else {
				return false;
			}
		}
		cur = new BSTreeNode<k>(key);
		if (cur->_key > parent->_key) {
			parent->_right = cur;
		}
		else if (cur->_key < parent->_key) {
			parent->_left = cur;
		}
		return true;
	}

	bool find(const k& key) {
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key) {
				cur = cur->_right;
			}
			else if (cur->_key > key) {
				cur = cur->_left;
			}
			else {
				return true;
			}
		}
		return false;
	}

	bool Erase(const k& key) {
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key) {
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key > key) {
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				//1.左为空
				if (cur->_left == nullptr) {
					if (cur == _root) {
						_root = cur->_right;
					}
					else if (parent->_left == cur) {
						parent->_left = cur->_right;
					}
					else {
						parent->_right = cur->_right;
					}
					delete cur;
				}
				//2.右为空
				else if (cur->_right == nullptr)
				{
					if (cur == _root) {
						_root = cur->_left;
					}
					else if (parent->_left == cur) {
						parent->_left = cur->_left;
					}
					else {
						parent->_right = cur->_left;
					}
					delete cur;
				}
				//3.左右都不为空
				else
				{
					//找右树最小节点替代,也可以是左树最大节点替代(这里找的右树的最小结点)
					Node* pminright = cur; //preminright
					Node* minright = cur->_right;
					while (minright->_left) {
						pminright = minright;
						minright = minright->_left;
					}
					cur->_key = minright->_key;
					if (pminright->_left == minright) {
						//minright的最小节点没有左子树且为pminright的左孩子
						pminright->_left = minright->_right;
					}
					else
					{
						//minright的最小节点没有左子树且为pminright的右孩子
						pminright->_right = minright->_right;
					}
					delete minright;
				}
				return true;
			}
		}
		return false;
	}
	void InOrder() {
		_InOrder(_root);
		cout << endl;
	}
	void _InOrder(Node* root) {
		if (root == nullptr) {
			return;
		}
		_InOrder(root->_left);
		cout << root->_key << "  ";
		_InOrder(root->_right);
		}

	protected:
		Node* Copy(Node* _root) {
			if (_root == nullptr)
				return nullptr;
			Node* newRoot = new Node(_root->_key);
			newRoot->_left = Copy(_root->_left);
			newRoot->_right = Copy(_root->_right);
			return newRoot;
		}

		void Destroy(Node* root) {
			if (root == nullptr) {
				return;
			}
			Destroy(root->_left);
			Destroy(root->_right);
			delete root;
			root = nullptr;
		}

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

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

		bool _EraseR(Node*& root, const k& key) {
			if (root == nullptr)
				return false;

			if (root->_key < key)
			{
				return _EraseR(root->_right, key);
			}
			else if (root->_key > key)
			{
				return _EraseR(root->_left, key);
			}
			else
			{
				Node* del = root;

				// 开始准备删除
				if (root->_right == nullptr)
				{
					root = root->_left;
				}
				else if (root->_left == nullptr)
				{
					root = root->_right;
				}
				else
				{
					Node* maxleft = root->_left;
					while (maxleft->_right)
					{
						maxleft = maxleft->_right;
					}

					swap(root->_key, maxleft->_key);

					return _EraseR(root->_left, key);
				}

				delete del;

				return true;
			}
		}
	};
};

key-value

cpp 复制代码
namespace key_value
{
	template<class K, class V>
	struct BSTreeNode
	{
		BSTreeNode<K, V>* _left;
		BSTreeNode<K, V>* _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 Insert(const K& key, const V& value)
		{
			if (_root == nullptr)
			{
				_root = new Node(key, value);
				return true;
			}

			Node* parent = nullptr;
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else
				{
					return false;
				}
			}

			cur = new Node(key, value);
			// 链接
			if (parent->_key < key)
			{
				parent->_right = cur;
			}
			else
			{
				parent->_left = cur;
			}

			return true;
		}

		Node* Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (cur->_key < key)
				{
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					cur = cur->_left;
				}
				else
				{
					return cur;
				}
			}

			return nullptr;
		}

		bool Erase(const K& key)
		{
			Node* parent = nullptr;
			Node* cur = _root;

			while (cur)
			{
				if (cur->_key < key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else
				{
					// 删除
					// 1、左为空
					if (cur->_left == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_right;
						}
						else
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_right;
							}
							else
							{
								parent->_right = cur->_right;
							}
						}

						delete cur;

					} // 2、右为空
					else if (cur->_right == nullptr)
					{
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else
						{
							if (parent->_left == cur)
							{
								parent->_left = cur->_left;
							}
							else
							{
								parent->_right = cur->_left;
							}
						}

						delete cur;
					}
					else
					{
						// 找右树最小节点替代,也可以是左树最大节点替代
						Node* pminRight = cur;
						Node* minRight = cur->_right;
						while (minRight->_left)
						{
							pminRight = minRight;
							minRight = minRight->_left;
						}

						cur->_key = minRight->_key;

						if (pminRight->_left == minRight)
						{
							pminRight->_left = minRight->_right;
						}
						else
						{
							pminRight->_right = minRight->_right;
						}

						delete minRight;
					}

					return true;
				}
			}

			return false;
		}


		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}

	protected:
		void _InOrder(Node* root)
		{
			if (root == nullptr)
				return;

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

测试用例

cpp 复制代码
#include<iostream>
#include"BSTree.h"

using namespace std;
void TestBSTree()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	key::BSTree<int> t1;

	for (auto e : a)
	{
		t1.Insert(e);
	}

	t1.InOrder();

	t1.Erase(4);
	t1.InOrder();

	t1.Erase(14);
	t1.InOrder();

	t1.Erase(3);
	t1.InOrder();

	t1.Erase(8);
	t1.InOrder();


	for (auto e : a)
	{
		cout << "delete:" << e << "    ";
		t1.Erase(e);
		t1.InOrder();
	}

	t1.InOrder();
}

void TestBSTree2()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	key::BSTree<int> t1;

	for (auto e : a)
	{
		t1.InsertR(e);
	}
	t1.InOrder();

	t1.EraseR(10);
	t1.EraseR(14);
	t1.EraseR(13);
	t1.InOrder();


	for (auto e : a)
	{
		t1.EraseR(e);
		t1.InOrder();
	}

	t1.InOrder();
}

void TestBSTree3()
{
	int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
	key::BSTree<int> t1;
	for (auto e : a)
	{
		t1.InsertR(e);
	}

	t1.InOrder();

	key::BSTree<int> t2(t1);
	t2.InOrder();
}

void TestBSTree4()
{
	key_value::BSTree<string, string> dict;
	dict.Insert("sort", "排序");
	dict.Insert("left", "左边");
	dict.Insert("right", "右边");
	dict.Insert("string", "字符串");
	dict.Insert("insert", "插入");
	dict.Insert("erase", "删除");

	string str;
	while (cin >> str)
	{
		auto ret = dict.Find(str);
		if (ret)
		{
			cout << ":" << ret->_value << endl;
		}
		else
		{
			cout << "无此单词" << endl;
		}
	}
}

void TestBSTree5()
{
	string arr[] = { "西瓜", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉", "梨" };

	key_value::BSTree<string, int> countTree;
	for (auto str : arr)
	{
		//key_value::BSTreeNode<string, int>* ret = countTree.Find(str);
		auto ret = countTree.Find(str);
		if (ret == nullptr)
		{
			countTree.Insert(str, 1);
		}
		else
		{
			ret->_value++;
		}
	}

	countTree.InOrder();
}


int main()
{
	TestBSTree();
	cout << "1" << endl;
	TestBSTree2();
	cout << "2" << endl;
	TestBSTree3();
	cout << "3" << endl;
	//TestBSTree4();
	cout << "4" << endl;
	TestBSTree5();
	cout << "5" << endl;
	return 0;
}
相关推荐
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
versatile_zpc6 小时前
C++初阶:类和对象(上)
开发语言·c++
小鱼仙官6 小时前
MFC IDC_STATIC控件嵌入一个DIALOG界面
c++·mfc
神仙别闹6 小时前
基本MFC类框架的俄罗斯方块游戏
c++·游戏·mfc
ChoSeitaku6 小时前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
娅娅梨6 小时前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
兵哥工控6 小时前
MFC工控项目实例二十九主对话框调用子对话框设定参数值
c++·mfc
Fuxiao___7 小时前
不使用递归的决策树生成算法
算法
我爱工作&工作love我7 小时前
1435:【例题3】曲线 一本通 代替三分
c++·算法