当前位置: 首页 > article >正文

二叉搜索数

二叉搜索数概念

**二叉搜索数(BST Binary Search Tree)😗*一颗二叉树,可以为空或者不为空,满足以下性质:

  1. 若左子树不为空,则左子树上的所有节点的值小于根节点的值。
  2. 若右子树不为空,则右子树上所有节点的值大于根节点的值。
  3. 左右子树均为二叉搜索树

模拟实现

基本结构

节点的结构体TreeNode

template<class T>
struct TreeNode
{

	TreeNode(const T& data = T())
		: _pLeft(nullptr), _pRight(nullptr), _data(data)
	{}
	TreeNode<T>* _pLeft;
	TreeNode<T>* _pRight;
	T _data;
};

二叉搜索树的类

template<class T>
class BSTree
{
	typedef TreeNode<T>* pNode;
	typedef TreeNode<T> Node;
public:
	pNode _pRoot;
    

2.构造与析构

BSTree() : _pRoot(nullptr)
	{}
	~BSTree()
	{
		BSTreeDestroy(_pRoot);
	}
	void BSTreeDestroy(pNode obj)
	{
		
		if (!obj)
		{
			return;
	}
		BSTreeDestroy(obj->_pLeft);
		BSTreeDestroy(obj->_pRight);
		delete obj;
	}

析构通过递归的方式实现

增删查

二叉搜索树的查找:

  • 从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。
  • 最多查找高度次,走到到空,还没找到,这个值不存在。
pNode find(const T& data)
	{
		pNode cur = _pRoot;
		while (data <= (cur->_data)&&cur!=nullptr)
		{
			if (T == cur->_data)
			{
				return cur;
		}
			cur = cur->_pLeft;
		}
		while (cur)
		{
			if (data == cur->_data)
			{
				return cur;
			}
			cur = cur->_pRight;
		}
		return nullptr;
			
	}

二叉搜索树的插入

插入的具体过程如下:
树为空,则直接新增节点,赋值给root指针
树不空,按二叉搜索树性质查找插入位置,插入新节点

bool Insert(const T& data)
	{
		// 如果树为空,直接插入
		if (nullptr == _pRoot)
		{
			_pRoot = new Node(data);
			return true;
		}
		// 按照二叉搜索树的性质查找data在树中的插入位置
		pNode pCur = _pRoot;
		// 记录pCur的双亲,因为新元素最终插入在pCur双亲左右孩子的位置
		pNode pParent = nullptr;
		while (pCur)
		{
			pParent = pCur;
			if (data < pCur->_data)
				pCur = pCur->_pLeft;
			else if (data > pCur->_data)
				pCur = pCur->_pRight; // 元素已经在树中存在
			else
				return false;
		}
		// 插入元素
		pCur = new Node(data);
		if (data < pParent->_data)
			pParent->_pLeft = pCur;
		else
			pParent->_pRight = pCur;
		return true;
	}

二叉搜索树的删除

分几种情况

  • 如果被删除节点只有左孩子节点或者没有左右孩子节点则直接删除
  • 如果被删除节点只有右孩子节点或者没有左右孩子节点直接删除
  • 如果被删除节点同时拥有左右孩子节点则,从左子树中找到最大值或者从右子树中找到最小值替换被删除节点后,再删除。因为左子树的最大值也一定小于右子树的所有值的同时也大于左子树所有值。同理,右子树的最小值一定大于左子树所有的值并且小于右子树所有的值这样替换之后仍然是一个二叉搜索树。
bool Erase(const T& data)
	{
		// 如果树为空,删除失败
		if (nullptr == _pRoot)
			return false;
		// 查找在data在树中的位置
		pNode pCur = _pRoot;
		pNode pParent = nullptr;
		while (pCur)
		{
			if (data == pCur->_data)
				break;
			else if (data < pCur->_data)
			{
				pParent = pCur;
				pCur = pCur->_pLeft;
			}
			else
			{
				pParent = pCur;
				pCur = pCur->_pRight;
			}
		}
		// data不在二叉搜索树中,无法删除
		if (nullptr == pCur)
			return false;
		
		if (nullptr == pCur->_pRight)
		{
			// 当前节点只有左孩子或者左孩子为空---可直接删除
			pParent->_pLeft = pCur->_pLeft;
			delete pCur;
			
		}
		else if (nullptr == pCur->_pLeft)
		{
			pParent->_pRight = pCur->_pRight;
			// 当前节点只有右孩子---可直接删除
			delete pCur;
			
		}
		else
		{
			pNode pdel = pCur;

			while (pCur->_pLeft)
			{
				pCur = pCur->_pLeft->_pRight;
			}
			std::swap(*pCur, *pdel);
			delete pdel;
		}
		return true;
	}

3.中序遍历二叉搜索树

中序遍历一个二叉搜索树一定是有序的

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

		_InOrder(root->_pLeft);
		cout << ":" << root->_data << endl;
		_InOrder(root->_pRight);
	}
}

http://www.kler.cn/a/329260.html

相关文章:

  • React|bpmn.js|react-bpmn使用示例详解
  • C# 异常处理、多个异常、自定义异常处理
  • thinkphp6 入门(2)--视图、渲染html页面、赋值
  • ES6进阶知识二
  • UniApp在Vue3的setup语法糖下自定义组件插槽详解
  • 三维测量与建模笔记 - 点特征提取 - 4.3 Harris特征点
  • Arch - 架构安全性_传输(Transport Security)
  • 【MySQL报错】---Data truncated for column ‘age‘ at row...
  • QT-MySQL QSqlDatabase: QMYSQL driver not loaded
  • LeetCode题练习与总结:行程和用户--262
  • 深度学习---------------------------深度循环神经网络
  • 浅谈计算机神经网络基础与应用
  • MySQL vs PostgreSQL:2024年深度对比与选择指南
  • Kotlin:1.8.0 的新特性
  • 开源23.6k star 一款即用型 OCR,支持 80+ 种语言和所有流行的书写脚本,只需几行代码即可实现文字识别功能。
  • 网易云多久更新一次ip属地
  • Java研学-BootStrapTable插件
  • $_POST = file_get_contents(“php://input“);是什么意思
  • C语言指针详解与应用(不断更新)
  • MongoDB 入门及实践
  • 【cache】浅析四种常用的缓存淘汰算法 FIFO/LRU/LFU/W-TinyLFU
  • MongoDB 聚合管道
  • Springboot3 + MyBatis-Plus + MySql + Vue + ProTable + TS 实现后台管理商品分类(最新教程附源码)
  • Webpack和GuIp打包原理以及不同
  • IDM下载器如何下载网盘文件 IDM下载器支持哪些网盘
  • 【数据库】Java 集成mongodb— MongoTemplate 详解