二叉树搜索树的应用

news2024/11/25 10:00:39

二叉树搜索树的应用

  • 1. 二叉树搜索树的应用
  • 2. 二叉搜索树的性能分析
  • 3. 二叉树进阶面试题

1. 二叉树搜索树的应用

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

改造二叉搜索树为KV结构

#pragma once
#include <iostream>
using namespace std;

namespace KV
{
	template <class K,class V>
	struct BSTreeNode
	{
		BSTreeNode<K,V>* _left;
		BSTreeNode<K,V>* _right;
		K _key;
		V _value;	

		BSTreeNode(const K& key, const V& value)
			:_left(nullptr)
			, _right(nullptr)
			, _key(key)
			,_value(value)
		{}
	};

	template <class K,class V>
	class BSTree
	{
		typedef BSTreeNode<K,V> Node;
	public:
		//插入
		bool Insert(const K& key, const V& value)
		{
			if (_root == nullptr)
			{
				_root = new Node(key,value); 
				return true;
			}
			Node* cur = _root;
			Node* parent = nullptr;
			while (cur)
			{
				parent = cur;
				if (key > cur->_key)
				{
					cur = cur->_right;
				}
				else if (key < cur->_key)
				{
					cur = cur->_left;
				}
				else
				{
					return false;
				}
			}
			cur = new Node(key,value);
			if (key > parent->_key)
			{
				parent->_right = cur;
			}
			if (key < parent->_key)
			{
				parent->_left = cur;
			}
			return true;
		}
		//中序打印
		void InOrder()
		{
			_InOrder(_root);
			cout << endl;
		}
		//查找
		Node * Find(const K& key)
		{
			Node* cur = _root;
			while (cur)
			{
				if (key > cur->_key)
				{
					cur = cur->_right;
				}
				else if (key < cur->_key)
				{
					cur = cur->_left;
				}
				else
				{
					return cur;
				}
			}
			return nullptr;
		}
		//删除
		bool Erase(const K& key)
		{
			Node* cur = _root;
			Node* parent = nullptr;
			while (cur)
			{
				if (key > cur->_key)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (key < cur->_key)
				{
					parent = cur;
					cur = cur->_left;
				}
				else
				{
					//开删
					if (cur->_left == nullptr)
					{//左为空
						if (cur == _root)
						{
							_root = cur->_right;
						}
						else if (cur == parent->_left)
						{
							parent->_left = cur->_right;
						}
						else
						{
							parent->_right = cur->_right;
						}
					}
					else if (cur->_right == nullptr)
					{//右为空
						if (cur == _root)
						{
							_root = cur->_left;
						}
						else if (cur == parent->_left)
						{
							parent->_left = cur->_left;
						}
						else
						{
							parent->_right = cur->_left;
						}
					}
					else
					{//左右都不为空
						Node* SubLeft = cur->_right;
						Node* _parent = cur;
						while (SubLeft->_left)
						{
							_parent = SubLeft;
							SubLeft = SubLeft->_left;
						}
						swap(cur->_key, SubLeft->_key);

						if (SubLeft == _parent->_left)
						{
							_parent->_left = SubLeft->_right;
						}
						else
						{
							_parent->_right = SubLeft->_right;
						}
					}
					return true;
				}
			}
			return false;
		}
	private:

		void _InOrder(Node* root)
		{
			if (root == nullptr)
			{
				return;
			}
			_InOrder(root->_left);
			cout << root->_key << ":" << root->_value << endl;
			_InOrder(root->_right);
		}

	private:
		Node* _root = nullptr;
	};

}

统计水果出现次数

int main()
{
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", 
		"西瓜","苹果", "香蕉", "苹果", "香蕉" };
	KV::BSTree<string, int> CountTree;

	for (auto &e : arr)
	{
		KV::BSTreeNode<string, int>* ret = CountTree.Find(e);
		if (ret == nullptr)
		{
			CountTree.Insert(e,1);
		}
		else
		{
			ret->_value++;
		}
	}
	CountTree.InOrder();
	return 0;
}

在这里插入图片描述


输入单词,查找单词对应的中文翻译

int main()
{
	KV::BSTree<string, string> dict;
	dict.Insert("sort", "快排");
	dict.Insert("left", "左边");
	dict.Insert("right", "右边");
	dict.Insert("insert", "插入");
	dict.Insert("key", "键值");

	string str;
	while (cin>>str)
	{
		KV::BSTreeNode<string, string>* ret = dict.Find(str);
		if (ret)
		{
			cout << ret->_value << endl;
		}
		else
		{
			cout << " 无此单词" << endl;
		}
	}
	return 0;
}

在这里插入图片描述

2. 二叉搜索树的性能分析

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

在这里插入图片描述

最优情况下,二叉搜索树为完全二叉树(或者接近完全二叉树),其平均比较次数为: l o g 2 N log_2 N log2N
最差情况下,二叉搜索树退化为单支树(或者类似单支),其平均比较次数为: N 2 \frac{N}{2} 2N

3. 二叉树进阶面试题

这些题目更适合使用C++完成,难度也更大一些

  1. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

  2. 二叉树搜索树转换成排序双向链表

  3. 二叉树创建字符串
    (本章完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1167637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redo Log(重做日志)的刷盘策略

1. 概述 Redo Log&#xff08;重做日志&#xff09;是 InnoDB 存储引擎中的一种关键组件&#xff0c;用于保障数据库事务的持久性和崩溃恢复。InnoDB 将事务所做的更改先记录到重做日志&#xff0c;之后再将其应用到磁盘上的数据页。 刷盘策略&#xff08;Flush Policy&#x…

Spring底层原理(六)

Spring底层原理(六) 本章内容 介绍AOP的实现方式、JDK代理的模拟实现与源码 AOP的实现方式 使用代理模式 jdk动态代理cglib动态代理 使用aspectj的编译器&#xff0c;该编译器会直接对字节码进行修改&#xff0c;可以实现静态方法增强 使用javaagent,在jvm option中指定-…

MYSQL 8.0 配置CDC(binlog)

CDC&#xff08;Change Data Capture&#xff09;即数据变更抓取&#xff0c;通过源端数据源开启CDC&#xff0c;ROMA Connect 可实现数据源的实时数据同步以及物理表的物理删除同步。这里介绍通过开启Binlog模式CDC功能。 注意&#xff1a;1、使用MYSQL8.0及以上版本。 2、不…

快讯|2024 财年第一季度 Tubi 收益增长了 30%

2024 财年第一季度 Tubi 收益增长了 30%&#xff0c;月活跃用户达到了 7000 万 近日&#xff0c;在 2024 财年第一季度财务收益电话会议上&#xff0c;Fox 执行主席兼 CEO Lachlan Murdoch 对 Tubi 的增长表示赞赏&#xff1a;“Tubi 又多了一个令人羡慕的季度&#xff0c;收入…

电脑技巧:台式机噪音非常大的几个原因以及解决办法

目录 一、CPU风扇灰尘太厚、风扇轴承老化 二、电源风扇有灰尘或者老化 三、显卡风扇有灰尘或者老化 四、硬盘老化导致的电脑主机声音大 五、台式机CPU风扇声音过大 今天小编给大家分享台式机噪音非常大的几个原因以及解决办法&#xff0c;值得收藏&#xff01; 一、CPU风…

Typecho V1.2.1 博客更换域名还原

网站老是到期或则要换服务器&#xff08;IP地址&#xff09;&#xff0c;单独改IP老是有图片不能加载&#xff0c;出个完整的迁移教程&#xff1a; 系统环境&#xff1a;Ubuntu 2204 宝塔面板 8.0.3 Nginx1.22 PHP 8.1 MySQL 5.7 备份 进入宝塔将网站根目录直接压缩&#xff0…

如何调试 Dubbo 协议调用过程

微服务架构下的快速交付、灵活部署等优势使得 Dubbo 协议已成为了当今互联网基础建设里的一大热点。 Dubbo 协议是一款由阿里巴巴开发并开源的一款高性能 Java RPC 框架&#xff0c;凭借着高效的远程调用、服务注册与发现、灵活的配置等特点&#xff0c;在微服务后端开发场景中…

Excel自学三部曲_Part3:Excel工作场景实战(四)

文章目录 四、高级函数与数据连接1. 多窗口操作2. VLOOKUP函数3. XLOOKUP函数4. CSV数据格式 四、高级函数与数据连接 1. 多窗口操作 如何将两张子表数据&#xff08;战区信息、城市信息&#xff09;连接到主表数据&#xff08;成交数据&#xff09;&#xff0c;增加主要数据的…

AI识别网关助力打造防溺水监测预警系统

防溺水监测预警系统的应用场景广泛&#xff0c;常见的诸如海边、河道、湖泊、泳池等多种场景&#xff0c;均可借助防溺水监测预警系统加强保障民众人身安全。随着科技水平不断提升&#xff0c;防溺水监测预警系统不断融合人工智能、视觉识别、物联网等先进技术&#xff0c;能够…

三季度业绩狂飙后,贝泰妮将开启集团化运营的“中场战事”?

双十一前夕&#xff0c;贝泰妮交出了一份亮眼的答卷。 得益于销售端和研发端的发展动能强劲&#xff0c;第三季度贝泰妮营收10.64亿元&#xff0c;同比增长25.77%&#xff1b;扣非净利润1.34亿元&#xff0c;同比增长39.88%。 如此亮眼的业绩&#xff0c;自然引得资本市场侧目…

【Python】多进程线程与CPU核数

多进程数量设置为CPU核数&#xff0c;或者略小于CPU核数&#xff1b;多线程数量&#xff0c;如果是CPU密集任务设为1&#xff1b;如果是IO密集设为合理的值&#xff1b;IO密集型&#xff1a;系统运作&#xff0c;大部分的状况是CPU 在等I/O &#xff08;硬盘/内存&#xff09;的…

单链表的建立(头插法、尾插法)(数据结构与算法)

如果要把很多个数据元素存到一个单链表中&#xff0c;如何操作&#xff1f; 1.初始化一个单链表 2. 每次取一个数据元素&#xff0c;插入到表尾/表头 1. 尾插法建立单链表 尾插法建立的单链表元素顺序与输入数据集合的顺序相同&#xff0c;即按照输入数据的顺序排列。 使用尾插…

【蓝桥杯选拔赛真题09】C++输出回文数 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

目录 C/C++输出回文数 一、题目要求 1、编程实现 2、输入输出 二、算法分析

MySQL中表的增删改查

目录 一、CRUD 二、新增&#xff08;Create&#xff09; &#xff08;1&#xff09;语法 &#xff08;2&#xff09;单行数据全列插入 &#xff08;3&#xff09;多行数据指定列插入 三、查询&#xff08;Retrieve&#xff09; &#xff08;1&#xff09;语法 …

vue3 + vite 安装配置及项目创建

node 和 npm 安装就不讲了&#xff0c;需要注意的是 node 需要版本是 16 以上。 VUE官网&#xff1a; https://cn.vuejs.org/ 一. 安装vue vite 1. 安装vue 方法一&#xff1a;<script> 标签 CDN 引入方式 <script src"https://unpkg.com/vue3/dist/vue.glo…

小米11 安装面具magisk 实现root

为了在安卓上抓包chatgpt 只能root小米11 来安装抓包工具小黄鸟 才能安装根证书来解析https。 1.官方解锁 2.下载小米11 安卓12 的开发版本 venus_images_V13.0.6.1.15.DEV_20220308.0000.00_12.0_cn_cb6b0c891f.tgz 进入刷机fastboot 3.进系统开启usb调试模式&#xff0c;…

GraphPad Prism v10.0.0.3(医学统计分析绘图软件)

GraphPad Prism 是一款医学统计和绘图软件&#xff0c;主要用于生物医学研究、实验设计和数据分析。以下是 GraphPad Prism 的主要功能和特点&#xff1a; 数据导入和整理&#xff1a;GraphPad Prism 可以导入各种数据格式&#xff0c;并提供直观的界面用于整理、编辑和管理数据…

PY32F071单片机,主频最高72 M,带一路DAC,USB

PY32F071 系列微控制器采用高性能的 32 位 ARM Cortex-M0内核&#xff0c;宽电压工作范围的 MCU。嵌入高达128 Kbytes flash 和 16 Kbytes SRAM 存储器&#xff0c;最高工作频率 72 MHz。包含多种不同封装类型多款产品。芯片集成多路 I2C、SPI、USART 等通讯外设&#xff0c;1 …

linux中各种最新网卡2.5G网卡驱动,不同型号的网卡需要不同的驱动,整合各种网卡驱动,包括有线网卡、无线网卡、Wi-Fi热点

linux中各种最新网卡2.5G网卡驱动&#xff0c;不同型号的网卡需要不同的驱动&#xff0c;整合各种网卡驱动&#xff0c;包括有线网卡、无线网卡、自动安装Wi-Fi热点。 最近在做路由器二次开发&#xff0c;现在市面上卖的新设备&#xff0c;大多数都采用了2.5G网卡&#xff0c;…

flutter项目引入本地静态图片资源并展示

想要在flutter中引入静态资源&#xff0c;需要配置pubspec.yaml&#xff0c;将本地的静态资源添加到assets下面&#xff1a; 然后在flutter引入这些静态资源&#xff1a; Image.asset("images/squick.png") 就可以在app中看到这个图片了&#xff1a; 也可以使用网…