数据结构——二叉搜索树

一、概念

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

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

二、二叉搜索树的操作

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树和红黑树中解决。请大家继续锁定,精彩不停更!!!

相关推荐
Re.不晚3 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
幸运超级加倍~2 小时前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan201903132 小时前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法2 小时前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR2 小时前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer2 小时前
快乐数算法
算法·leetcode·职场和发展
小芒果_012 小时前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛