数据结构——二叉搜索树

一、概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

  • 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
  • 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
  • 它的左右子树也分别为二叉搜索树

二、二叉搜索树的操作

2.1 查找

  1. 从根开始比较,比根大的向右边走查找,比根小的向左边走查找
  2. 最多查找高度次,走到空还没有找到的,这个值就不存在

2.2 插入

插入的具体过程为:

  1. 树为空,则直接新增节点,赋值给root节点
  2. 树不空,按二号搜索树性质查找插入位置,插入新节点

2.3 删除

首先查找元素是否在二叉搜索树中,如果不存在,则返回,否则要删除的节点可能有下面四种情况:

  1. 要删除的节点无孩子节点
  2. 要删除的节点只有左孩子结点
  3. 要删除的节点只有右孩子节点
  4. 要删除的节点有左、右孩子节点

看起来有待删除的节点有4种情况,实际情况1可以与情况2或者3合并起来,因此真正的情况如下:

  • 删除该节点且使被删除节点的双亲节点指向被删除节点的左孩子节点------直接删除
  • 删除该节点且使被删除节点的双亲节点指向被删除节点的右孩子节点------直接删除
  • 在它的右子树中寻找中序下的第一个节点(关键码最小),用它的值填补到被删除节点中,再来处理该节点的删除问题------替换法删除

三、二叉搜索树的实现

cpp 复制代码
template<class T>
struct BSTNode
{
	BSTNode(const T& data = T())
		: _pLeft(nullptr), _pRight(nullptr), _data(data)
	{}
	BSTNode<T>* _pLeft;
	BSTNode<T>* _pRight;
	T _data;
};

template<class T>
class BSTree
{
	typedef BSTNode<T> Node;
	typedef Node* PNode;
public:
	BSTree() : _pRoot(nullptr)
	{}
private:
	PNode _pRoot;
};

3.1 插入

cpp 复制代码
// 插入
	bool Insert(const T& data)
	{
		
		if (nullptr == _pRoot)
		{
			_pRoot = new Node(data);
			return true;
		}
		
		PNode pCur = _pRoot;
		
		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;
	}

	

3.2 删除

cpp 复制代码
// 删除
	bool Erase(const T& data)
	{
		if (nullptr == _pRoot)
			return false;

		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;
			}
		}

		if (nullptr == pCur)
			return false;

		return true;
	}

四、二叉搜索树的性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。

对有n个节点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是节点在二叉搜索树的深度的函数,即节点越深,比较次数越多。

但对于同一个关键码集合 ,如果各关键码插入的次序不同 ,可能得到不同结构的二叉搜索树。
最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其时间复杂度为O(logN)

最差情况下,二叉搜索树退化为单支树(或者类似单支),其时间复杂度为O(N)

那么问题来了,如果退化为单支树,二叉搜索树的优势就失去了,该怎么进行改进,使不论什么次序插入关键码,二叉搜索树的性能都能达到最优呢?这个会在后续AVL树和红黑树中解决。请大家继续锁定,精彩不停更!!!

相关推荐
CoovallyAIHub16 小时前
中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
深度学习·算法·计算机视觉
NAGNIP16 小时前
Serverless 架构下的大模型框架落地实践
算法·架构
moonlifesudo17 小时前
半开区间和开区间的两个二分模版
算法
moonlifesudo17 小时前
300:最长递增子序列
算法
CoovallyAIHub1 天前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
CoovallyAIHub1 天前
英伟达ViPE重磅发布!解决3D感知难题,SLAM+深度学习完美融合(附带数据集下载地址)
深度学习·算法·计算机视觉
聚客AI2 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v2 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工2 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农2 天前
【React用到的一些算法】游标和栈
算法·react.js