栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

二叉搜索树(基础)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二叉搜索树(基础)

二叉搜索树(BinarySearchTree)

所有左子树的值都小于根,所有右子树的值都大于根
用处:在内存中查找
最多查找高度次
如果能做到满二叉树或完全二叉树,在中国14亿人中找到心动的人只需要31次,10亿是30次(2的三十次方)

查找的话:需要后期的平衡二叉树,和AVL树

搜索二叉树中序遍历时一定程度上是有序的,所以又被叫做排序二叉树

比较数据的大小,我们在声明模板的时候一般申请成key - --class K
Insert操作
先序遍历可以排序+去重
查找Find也很简单

删除操作

#pragma once
#include
#include

using namespace std;

//二叉树以后,模板参数用K(key)
template
struct BSTreeNode
{
	BSTreeNode* left;
	BSTreeNode* right;
	K _val;

	BSTreeNode(const K& val)
		:left(nullptr)
		,right(nullptr)
		,_val(val)
	{}
};

template
class BSTree
{
	typedef BSTreeNode Node;
public:
	BSTree()
		:_root(nullptr)
	{}

	bool Insert(const K& val)
	{
		if (_root == nullptr)
		{
			_root = new Node(val);
			return true;
		}

		Node* parent = nullptr;
		Node* cur = _root;
		
		while (cur)
		{
			if (cur->_val < val)
			{
				parent = cur;
				cur = cur->right;
			}
			else if (cur->_val > val)
			{
				parent = cur;
				cur = cur->left;
			}
			else
			{
				return false;//树中不允许有相同的元素存在
			}
		}

		//已经找到了位置,开始放结点
		//想要链接的话,必须要通过parent
		//单靠自己所在位置是链接不了的
		cur = new Node(val);
		if (parent->_val < val)
		{
			parent->right = cur;
		}
		else
		{
			parent->left = cur;
		}
		return true;
	}

	bool Find(const K& val)
	{
		Node* cur = _root;
		while (cur)
		{
			if (cur->_val < val)
			{
				cur = cur->right;
			}
			else if (cur->_val > val)
			{
				cur = cur->left;
			}
			else
			{
				return true;
			}
		}
		return false;
	}

	bool Erase(const K& val)
	{
		Node* parent = nullptr;
		Node* cur = _root;
		//开始找需要删除的元素
		while (cur)
		{
			if (cur->_val < val)
			{
				parent = cur;
				cur = cur->right;
			}
			else if (cur->_val > val)
			{
				parent = cur;
				cur = cur->left;
			}
			else
			{
				//找到了以后分三种情况
				//1 .该结点没有孩子 2 .该节点没有孩子 3.该节点有两个孩子
				//前两种情况可以直接删除,最后一种情况可以用替换法删除
				//将左子树的最右结点(也就是最大结点)或者右子树的最小节点(最左)交换删除
				if (cur->left == nullptr)
				{
					//如果是根结点,特殊处理
					if (parent == nullptr)
					{
						_root = cur->right;
					}
					else
					{
						if (parent->left == cur)
						{
							parent->left = cur->right;
						}
						else
						{
							parent->right = cur->right;
						}
					}
					delete cur;
				}
				else if (cur->right == nullptr)
				{
					if (parent == nullptr)
					{
						_root = cur->left;
					}
					else
					{
						if (parent->left == cur)
						{
							parent->left = cur->left;
						}
						else
						{
							parent->right = cur->left;
						}
					}
					delete cur;
				}
				else
				{
					//该结点既有左孩子又有右孩子,那么我们找左树的最大或者右树的最小
					//在这里我们找右树的最小(也就是最左子树)
					Node* minParent = cur;
					Node* min = cur->right;
					//找小
					while (min->left)
					{
						minParent = min;
						min = min->left;
					}
					
					cur->_val = min->_val;
					
					if (minParent->left == min)
					{
						minParent->left = min->right;
					}
					else
					{
						minParent->right = cur->right;
					}
					delete min;
				}
				return true;
			}
			
		}
		//没有找到
		return false;
	}

	//递归写法写一个中序遍历
	// 中序遍历就是排升序
	//写一个_InOrder进行辅助递归
	void InOrder()
	{
		_InOrder(_root);
	}

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

		_InOrder(root->left);
		cout << root->_val << " ";
		_InOrder(root->right);
	}

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

	Node* FindR(Node* root, const K& key)
	{
		return _FindR(root, key);
	}

	bool EraseR(Node* root, const K& key)
	{
		_EraseR(root, key);
	}

private:
	bool _EraseR(Node* root, const K& key)
	{
		if (root == nullptr)
		{
			return false;
		}

		if (root->_val < key)
		{
			return _EraseR(root->right, key);
		}
		else if (root->_val > key)
		{
			return _EraseR(root->left, key);
		}
		else
		{
			Node* del = root;
			if (root->left == nullptr)
			{
				root = root->right;
			}
			else if (root->right == nullptr)
			{
				root = root->left;
			}
			else
			{
				Node* min = root->right;
				while (min)
				{
					min = min->left;
				}
				swap(min->_val, del->_key);

				_EraseR(root->right, key);
			}
			delete del;
		}
	}


	Node* _FindR(Node* root, const K& key)
	{
		if (root == nullptr)
		{
			return root;
		}

		if (root->_val < key)
		{
			return _FindR(root->right, key);
		}
		else if (root->_val > key)
		{
			return _FindR(root->left, key);
		}
		else
		{
			return root;
		}
	}

	bool _InsertR(Node*& root,const K& key)
	{
		if (root == nullptr)
		{
			root = new Node(key);
			return true;
		}

		if (root->_val < key)
		{
			return _InsertR(root->right, key);
		}
		else if (root->_val > key)
		{
			return _InsertR(root->left, key);
		}
		else
		{
			return false;
		}
	}

	Node* _root;
};


void TestBSTree()
{
	BSTree t;
	int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9,5,5 };
	
	for (auto e : a)
	{
		t.Insert(e);
	}
	
	t.InOrder();
	printf("n");
	t.Erase(5);
	t.InOrder();
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/892942.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号