深度探索二叉树之二叉搜索树

定义

概念

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

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

int a [] = {5,3,4,1,7,8,2,6,0,9};的二叉搜索树
在这里插入图片描述

常见操作

查找

  1. 如果key比他的父节点比他小,他的左子树指向parent,key比他的父节点比他大,他的左子树指向parent,
    在这里插入图片描述
    2,其他情况返回null

删除

删除要包括以下情况:

  1. 如果根节点为空直接返回false

在这里插入图片描述

  1. 先找到与要删除值相等的节点,然后分成以下情况:
    (1)、删除的节点左为空,但是右边不为空
    在这里插入图片描述
    在这里插入图片描述
    (2)、删除的节点右子树为空,但是左子树边不为空
    (3)、删除的节点右子树,左子树都不为空
    这里我们用替代法删除

(2)

在这里插入图片描述

在这里插入图片描述
(3)在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

插入

插入过程如下:

  1. 如果根节点为空直接插入的根节点

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210521182757690.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUwNDA4MzQw,size_16,color_FFFFFF,t_70

  1. 如果有重复的直接返回

在这里插入图片描述

  1. 如果以上情况不符合就找到节点为空的情况并保留他的父节点,比父节点大就插入到右边,比父节点小就插入到左边

在这里插入图片描述

遍历

  • 依次遍历左子树,右子树,直到为空就返回。

实现

k版本
代码如下:

template<class k>
struct tree {
	k _key;
	struct tree<k>* _left;
	struct tree<k>* _right;
	tree(const k&k):_key(k)
		,_left(nullptr),
		_right(nullptr)	{
	
	}
};//二叉数结构体
template<class k>
class SStree {
	typedef struct tree<k> Node;//二叉树节点
public:
	bool Insert(const k& k) {
		if (root == nullptr) {
			root = new Node(k);
			return true;

		}

		Node* parent = nullptr;
		Node* cur = root;
		while (cur) {


			if (cur->_key > k) {
				parent = cur;
				cur = cur->_left;

			}
			else if (cur->_key < k) {
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key == k) {
				return false;

			}

		}



		Node* node = new Node(k);
		if (k > parent->_key) {
			parent->_right = node;
		}
		else {

			parent->_left = node;
		}
		return true;
	}
	Node* find(const k& k)const {

		Node* _root = root;
		while (_root) {
			if (_root->_key > k) {
				_root = _root->_left;

			}
			else if (_root->_key < k) {
				_root = _root->_right;
			}
			else {
				return _root;
			}

		}
		return nullptr;
	}
	void indof(Node* _root) {
		if (_root == nullptr) {
			return;
		}
		indof(_root->_left);
		cout << _root->_key;
		indof(_root->_right);

	}
	void Indof() {
		indof(root);
		cout << endl;

	}
	bool erase(const k& k) {
		if (root == nullptr) {
			return false;

		}
		Node* cur = root;
		Node* parent = nullptr;
		while (cur) {
			if (cur->_key > k) {
				parent = cur->_left;
				cur = cur->_left;
			}
			else if (cur->_key < k) {
				parent = cur;
				cur = cur->_right;
			}
			else {
				//准备删除
				//佐为空
				//右为空
				//左右都为空
				if (cur->_left == nullptr) {
					//根节点的左为空
					if (root == cur) {
						root = cur->_right;

					}
					else {
						if (cur == parent->_left) {
							parent->_left = cur->_right;
						}
						else if (cur == parent->_right) {
							parent->_right = cur->_right;
						}
					}
					delete cur;
				}
				else if (cur->_right == nullptr) {
					if (root == cur) {
						root = cur->_left;

					}
					else {
						if (cur == parent->_left) {
							parent->_left = cur->_left;
						}
						else if (cur == parent->_right) {
							parent->_right = cur->_left;
						}
					}
					delete cur;
				}
				else {
					//替代法删除
					//找右数的最左节点
					//找左数的最右节点
					//要注意右子树的根可能就是最小节点
					Node* submin = cur->_right;
					Node* parentmin = cur;

					while (submin) {
						parentmin = submin;
						submin->_left;
					}
					if (parentmin->_left == submin) {
						parentmin->_left = submin->_right;
					}
					else {
						parentmin->_right = submin->_right;
					}
					delete submin;
				}
			}


			return false;
		}
	}
	private:
		Node* root = nullptr;

};

应用

  1. K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到的值。比如:给一个单词word,判断该单词是否拼写正确,具体方式如下:以单词集合中的每个单词作为key,构建一棵二叉搜索树在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。
  2. KV模型:每一个关键码key,都有与之对应的值Value,即<Key, Value>的键值对。该种方式在现实生活中非常常见:比如英汉词典就是英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文<word,
    chinese>就构成一种键值对;再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出现次数就是<word,
    count>就构成一种键值对。比如:实现一个简单的英汉词典dict,可以通过英文找到与其对应的中文,具体实现方式如下:<单词,中文含义>为键值对构造二叉搜索树,注意:二叉搜索树需要比较,键值对比较时只比较Key查询英文单词时,只需给出英文单词,就可快速找到与其对应的key

性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。 对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的 深度的函数,即结点越深,则比较次数越多。 但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:

在这里插入图片描述

在这里插入图片描述

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自首的小偷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值