数据结构与算法分析实验12 实现二叉查找树
实现二叉查找树
- 1、二叉查找树介绍
- 2.上机要求
- 3.上机环境
- 4.程序清单(写明运行结果及结果分析)
- 4.1 程序清单
- 4.1.1 头文件 TreeMap.h 内容如下:
- 4.1.2 实现文件 TreeMap.cpp 文件内容如下:
- 4.1.3 源文件 main.cpp 文件内容如下:
- 4.2 实现展效果示
- 5.上机体会
1、二叉查找树介绍
二叉查找树(Binary Search Tree, BST)是一种特殊的二叉树,其中每个节点都包含一个键值,并且满足以下性质:
- 左子树中的所有节点的键值小于当前节点的键值。
- 右子树中的所有节点的键值大于当前节点的键值。
- 左右子树也分别是二叉查找树。
二叉查找树的优缺点
- 优点
查找、插入和删除操作的平均时间复杂度为O(log n)。
结构简单,易于实现。 - 缺点
在最坏情况下(如树退化为链表),时间复杂度会退化为O(n)。
需要额外的平衡操作(如AVL树、红黑树)来保持树的平衡,避免性能退化。 - 二叉查找树是计算机科学中一种基础且重要的数据结构,理解其原理和操作对于深入学习算法和数据结构具有重要意义。
2.上机要求
基于二叉排序树,实现插入键值对、按照关键字查询、删除记录等操作
3.上机环境
visual studio 2022
Windows11 家庭版 64位操作系统
4.程序清单(写明运行结果及结果分析)
4.1 程序清单
4.1.1 头文件 TreeMap.h 内容如下:
#pragma once
#include<iostream>
//基于二叉排序树,实现插入键值对、按照关键字查询、删除记录等操作
#define maxsize 100using namespace std;
typedef string Key;
typedef string Val;typedef struct TNode { Key key;Val val;//struct TNode* parent; struct TNode* lcd; struct TNode* rcd;
}Tnode, * pTnode;void insert(pTnode& tree, Key key, Val val); //函数插入
void TreeCreate(pTnode& tree); //创建
void Min_Order_View(pTnode tree); //由索引从小到大展示
void Max_Order_View(pTnode tree); //由索引从大到小展示
void input(pTnode& tree); //键盘插入
int gethigh(pTnode tree); //得到这一层树的高度,可以通过它得到平衡因子
void deletee(pTnode& tree, Key key); //删除
void search(pTnode tree, Key key); //查找
int getfactor(pTnode tree); //得到平衡因子,尚且没有用到,方便拓展成平衡二叉树
4.1.2 实现文件 TreeMap.cpp 文件内容如下:
#include"TreeMap.h"void insert(pTnode& tree,Key key,Val val){if (tree == nullptr) {tree = new Tnode;tree->val = val;tree->key = key;tree->lcd = nullptr;tree->rcd = nullptr;return;}if (key == tree->key) {cout << "键值已经存在"; return;}else if (key < tree->key) {insert(tree->lcd, key, val);}else {insert(tree->rcd, key, val);}
}
void TreeCreate(pTnode& tree) {cout << "开始输入键值对,键值对都为q时退出>>\n";while (1) {Key key;Val val;cout << "Key>>"; cin >> key;cout << "Val>>"; cin >> val;if ((key == "q" || key == "Q") && (val == "q" || val == "Q"))break;else {insert(tree, key, val);}}cout << "输入成功\n";
}
void Min_Order_View(pTnode tree){if (tree!=nullptr) {if (tree->lcd)Min_Order_View(tree->lcd);cout << tree->key << "\t" << tree->val << endl;if (tree->rcd)Min_Order_View(tree->rcd);}else return;
}
/*** 该函数用于按最大顺序遍历二叉树。* 遍历顺序为:右子树 -> 当前节点 -> 左子树。* @param tree 指向二叉树根节点的指针。*/
void Max_Order_View(pTnode tree) {if (tree!=nullptr) {if (tree->rcd) Max_Order_View(tree->rcd);cout << tree->key << "\t" << tree->val << endl;if (tree->lcd) Max_Order_View(tree->lcd);}else return;
}
/*** 该函数用于向二叉树中插入一个新的节点。* 用户需要输入键值和对应的值,函数会将其插入到二叉树中。* @param tree 指向二叉树根节点的指针的引用。*/
void input(pTnode& tree){Key key; cout << "input key>>"; cin >> key;Val val; cout << "input val>>"; cin >> val;insert(tree, key, val);cout << "finish!" << endl;
}
/*** 该函数用于计算二叉树的高度。* 通过递归计算左子树和右子树的高度,返回较大的高度加1。* @param tree 指向二叉树根节点的指针。* @return 返回二叉树的高度。*/
int gethigh(pTnode tree) {int hl, hr;if (tree) {hl = gethigh(tree->lcd);hr = gethigh(tree->rcd);return hl > hr ? hl + 1 : hr + 1;}else return 1;
}
/*
deletee 函数用于从二叉搜索树中删除具有指定键值的节点。
该函数通过递归的方式查找并删除目标节点,同时处理了多种情况,
包括删除叶子节点、只有左子树或右子树的节点,以及同时拥有左右子树的节点。
*/
void deletee(pTnode& tree, Key key){if (tree == nullptr) {cout << "无对应键值" << endl;return;}if (key == tree->key) {if (tree->lcd == nullptr&&tree->rcd == nullptr) {//叶子delete tree;tree = nullptr; //呜呜请加上这句,bug所在cout << "OK1" << endl;return;}else if (tree->lcd == nullptr && tree->rcd != nullptr) {//没有左子树pTnode del = tree;tree = tree->rcd;delete del;cout << "OK2" << endl;return;}else if (tree->lcd != nullptr && tree->rcd == nullptr) {//没有右子树pTnode del = tree;tree = tree->lcd;delete del;cout << "OK3" << endl;return;}else {//左右子树都有pTnode move = tree->rcd;while (move->lcd != nullptr)//拿到替死鬼{move = move->lcd;}tree->key = move->key;tree->val = move->val;delete move;cout << "OK4" << endl;return;}}else if (key < tree->key) {if (tree->lcd)deletee(tree->lcd, key);}else {if (tree->rcd)deletee(tree->rcd, key);}
}
/*** @brief 在二叉搜索树中查找指定键值的节点* 该函数递归地在二叉搜索树中查找与给定键值匹配的节点。如果找到匹配的节点,则输出该节点的键值和对应的值;如果未找到,则输出提示信息。*/
void search(pTnode tree, Key key) {if (tree == nullptr) {cout << key << ":" << "不存在此键值" << endl;return;}if (tree->key == key) {cout << key << ":" << tree->val << endl;return;}else if (key < tree->key) {search(tree->lcd, key);}else {search(tree->rcd, key);}
}
int getfactor(pTnode tree){if (tree) return(gethigh(tree->lcd) - gethigh(tree->rcd));else return 0;
}
4.1.3 源文件 main.cpp 文件内容如下:
#include"TreeMap.h"
int main() {pTnode tree = nullptr;TreeCreate(tree); //创建cout << "从小到大索引" << endl; //从小到大输出Min_Order_View(tree);input(tree); //增加操作insert(tree, "my", "我的");cout << "从大到小索引" << endl; //从大到小输出Max_Order_View(tree);cout << "删除操作" << endl; //删除操作deletee(tree, "my");Max_Order_View(tree);cout << "查询操作" << endl; //查找操作search(tree, "hello");search(tree, "my");cout<<"\nget factor:"<<getfactor(tree);return 0;
}
4.2 实现展效果示
如左下图,输入部分:当全部是q时完成输入,可以看到,输入的索引是无序的。
如右上图,输出部分,按照关键字大小顺序从小到大,输出了键值对,提示我们插入一条信息。
如左下图我们输入hellow 你好w,由于代码中插入 my 我的 这个记录,再次展示的记录多了两条,同时这次采用从大到小的打印方法。
如右上图,代码中我们选择删除 my 关键字,提示OK1,表明我们删除了叶子节点,再次展示从大到小,不存在 my 节点,同时 search 操作对 hello 有效,对 my 无效。
5.上机体会
二叉查找树(Binary Search Tree,BST)是一种特殊类型的二叉树,它所有的根节点大于左子树的节点,小于右子树的节点。具有以下性质:
1、 如果左子树不为空,则左子树上的所有节点都小于根节点。
2、 如果右子树不为空,则右子树上的所有节点都大于根节点。
3、 左右子树也为搜索二叉树。
二叉查找树的常用操作有:插入、查找、删除、最大值、最小值等。
在二叉树的创建过程中,可以使用递归的方式。首先,将根节点的值设置为给定的值,然后递归地构建左子树和右子树。插入查找删除的理想时间复杂度为 O(log n),其中 n 是树的节点数。中序遍历输出二叉树则是很好的排序方法。通过实验,我们可以更加深入地理解二叉查找树的概念和性质,掌握二叉查找树的常见操作的实现方法。同时,我们也可以通过实验发现一些二叉查找树的应用场景,例如在数据库中的索引结构、文件系统中的目录结构等。需要注意的是,二叉查找树的性能高度依赖于树的平衡性。如果树的平衡性较差,可能会导致搜索效率降低。因此,在实际应用中,需要对二叉查找树进行适当的平衡调整,例如使用红黑树等自平衡二叉查找树。
相关文章:

数据结构与算法分析实验12 实现二叉查找树
实现二叉查找树 1、二叉查找树介绍2.上机要求3.上机环境4.程序清单(写明运行结果及结果分析)4.1 程序清单4.1.1 头文件 TreeMap.h 内容如下:4.1.2 实现文件 TreeMap.cpp 文件内容如下:4.1.3 源文件 main.cpp 文件内容如下: 4.2 实现展效果示5…...

使用 Semantic Kernel 调用 Qwen-VL 多模态模型
使用 Semantic Kernel 调用 Qwen-VL 多模态模型 一、引言 随着人工智能技术的不断发展,多模态模型逐渐成为研究的热点。Qwen-VL 是阿里云推出的大规模视觉语言模型,支持图像、文本等多种输入形式,并能够进行图像描述、视觉问答等多种任务。…...
请求内存算法题
题意描述 有两个数组输入: mem [32,128,64,192,256]表示有数组长度个设备,每个设备能提供分配的内存大小值(均为4的倍数),数组最大长度200000 reques [64,128,128,128,512]表示请求内存,在mem中找与请求内存大小最相近或相等的…...

(4)python开发经验
文章目录 1 使用ctypes库调用2 使用pybind11 更多精彩内容👉内容导航 👈👉Qt开发 👈👉python开发 👈 1 使用ctypes库调用 说明:ctypes是一个Python内置的库,可以提供C兼容的数据类型…...

深度剖析 GpuGeek 实例:GpuGeek/Qwen3-32B 模型 API 调用实践与性能测试洞察
深度剖析 GpuGeek 实例:GpuGeek/Qwen3-32B 模型 API 调用实践与性能测试洞察 前言 GpuGeek专注于人工智能与高性能计算领域的云计算平台,致力于为开发者、科研机构及企业提供灵活、高效、低成本的GPU算力资源。平台通过整合全球分布式数据中心资源&#…...

MindSpore框架学习项目-ResNet药物分类-数据增强
目录 1.数据增强 1.1设置运行环境 1.1.1数据预处理 数据预处理代码解析 1.1.2数据集划分 数据集划分代码说明 1.2数据增强 1.2.1创建带标签的可迭代对象 1.2.2数据预处理与格式化(ms的data格式) 从原始图像数据到 MindSpore 可训练 / 评估的数…...
e.g. ‘django.db.models.BigAutoField‘.
在Django框架中,django.db.models.BigAutoField 是一个用于数据库模型的字段类型,它用于自动增长的ID字段。这个字段类型特别适用于需要处理大量数据的应用,比如在大型网站或应用中,普通的 AutoField 可能不足以存储增长的ID值&am…...
ACM算法
在ACM模式下使用JavaScript/TypeScript获取输入值 在ACM编程竞赛或在线判题系统(如LeetCode、牛客网等)中,JavaScript/TypeScript需要特定的方式来获取输入值。以下是几种常见的获取输入的方法: 1. 使用Node.js的readline模块 这是最常见的处理ACM模式…...
MySQL入门指南:环境搭建与服务管理全流程
引言 各位开发者朋友们好!今天我们将开启MySQL的学习之旅 🌟 作为世界上最流行的开源关系型数据库,MySQL在Web应用、企业系统等领域占据着举足轻重的地位。无论你是刚入行的新手,还是想系统复习的老鸟,这篇教程都将为…...

【MySQL】别名设置与使用
个人主页:Guiat 归属专栏:MySQL 文章目录 1. 别名基础概念2. 列别名设置2.1 基础语法2.2 特殊字符处理2.3 计算字段示例 3. 表别名应用3.1 基础表别名3.2 自连接场景 4. 高级别名技术4.1 子查询别名4.2 CTE别名 5. 别名执行规则5.1 作用域限制5.2 错误用…...

【内网渗透】——S4u2扩展协议提权以及KDC欺骗提权
【内网渗透】——S4u2扩展协议提权以及KDC欺骗提权 文章目录 【内网渗透】——S4u2扩展协议提权以及KDC欺骗提权[toc]一:Kerberos 委派攻击原理之 S4U2利用1.1原理1.2两种扩展协议**S4U2Self (Service for User to Self)****S4U2Proxy (Service for User to Proxy)*…...
枢轴支压点策略
一种基于枢轴点(Pivot Point)的交易策略,主要用于在趋势行情中进行交易。 策略的核心思路是通过计算前一天的最高价、最低价和收盘价来确定当天的枢轴点,并据此计算出第一和第二阻力位以及第一和第二支撑位。 可以根据这些关键点位…...
Manus逆向工程:AI智能体的“思考”与“行动”
写在前面 本篇博客将基于 Manus 测试的行为日志,尝试反向推演其内部的核心逻辑。我们将探讨它如何巧妙地融合了计划-执行(Plan-Execute) 和 ReAct(Reasoning and Acting,即思考与行动) 两种范式,并灵活运用浏览器和 Python 解释器等工具来攻克复杂任务。 基本逻辑:从…...

Linux——CMake的快速入门上手和保姆级使用介绍、一键执行shell脚本
目录 一、前言 二、CMake简介 三、CMake与其他常见的构建、编译工具的联系 四、CMake入门 1、CMake的使用注意事项 2、基本的概念和术语 3、CMake常用的预定义变量 4、CMakeLists.txt文件的基本结构 五、上手实操 1、示例 编辑 2、一个正式的工程构建 2.1基本构…...
Keil5 MDK 安装教程
## 简介 Keil MDK(Microcontroller Development Kit)是ARM开发的一款集成开发环境(IDE),主要用于ARM Cortex-M系列微控制器的开发。MDK包含了μVision IDE和调试器、ARM C/C编译器、中间件组件等工具。本教程将指导您完…...
深入浅出 IPFS 在 DApps 和 NFT 中的应用:以 Pinata 实战为例
目录 IPFS背景什么是 IPFS?IPFS 在 DApps 与 NFT 中的作用什么是 Pinata?为什么使用它?使用原生IPFS上传下载文件(HTML + JavaScript 示例)使用Pinata上传下载文件(HTML + JavaScript 示例)注册并创建APIKey使用 Pinata 上传文件和JSON(HTML + JavaScript 示例)总结IP…...

如何高效集成MySQL数据到金蝶云星空
MySQL数据集成到金蝶云星空:SC采购入库-深圳天一-OK案例分享 在企业信息化建设中,数据的高效流转和准确对接是实现业务流程自动化的关键。本文将聚焦于一个具体的系统对接集成案例——“SC采购入库-深圳天一-OK”,详细探讨如何通过轻易云数据…...

通过POI实现对word基于书签的内容替换、删除、插入
一、基本概念 POI:即Apache POI, 它是一个开源的 Java 库,主要用于读取 Microsoft Office 文档(Word、Excel、PowerPoint 等),修改 或 生成 Office 文档内容,保存 为对应的二进制或 XML 格式&a…...

FlashInfer - 测试的GPU H100 SXM、A100 PCIe、RTX 6000 Ada、RTX 4090
FlashInfer - 测试的GPU H100 SXM、A100 PCIe、RTX 6000 Ada、RTX 4090 flyfish GPU 技术参数术语 1. Memory bandwidth (GB/s) 中文:显存带宽(单位:GB/秒) 定义:显存(GPU 内存)与 GPU 核心…...
MCP:开启AI的“万物互联”时代
MCP:开启AI的“万物互联”时代 ——从协议标准到生态革命的技术跃迁 引言:AI的“最后一公里”困境 在2025年的AI技术浪潮中,大模型已从参数竞赛转向应用落地之争。尽管模型能生成流畅的对话、创作诗歌甚至编写代码,但用户逐渐发现…...
企业级IP代理解决方案:负载均衡与API接口集成实践
在全球化业务扩张与数据驱动决策的背景下,企业级IP代理解决方案通过负载均衡技术与API接口集成,可有效应对高频请求、反爬机制及合规风险。以下是基于企业级场景的核心实践要点: 一、负载均衡与IP代理的深度协同 动态IP池的负载均衡策略 轮询…...
Vector和list
一、Vector和list的区别——从“它们是什么”到“区别在哪儿” 1. 它们是什么? Vector:类似于一排排整齐的书架(数组),存放元素时,元素排成一条线,连续存储。可以很快通过编号(索引…...

MongoDB从入门到实战之Windows快速安装MongoDB
前言 本章节的主要内容是在 Windows 系统下快速安装 MongoDB 并使用 Navicat 工具快速连接。 MongoDB从入门到实战之MongoDB简介 MongoDB从入门到实战之MongoDB快速入门 MongoDB从入门到实战之Docker快速安装MongoDB 下载 MongoDB 安装包 打开 MongoDB 官网下载页面&…...

Excelize 开源基础库发布 2.9.1 版本更新
Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Excel、WPS、OpenOffice 等办公软件创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式…...
package-lock.json能否直接删除?
package-lock.json能否直接删除? package-lock.json 生成工具:由 npm 自动生成。 触发条件:当运行 npm install 时,如果不存在 package-lock.json,npm 会创建它;如果已存在,npm 会根据它精确安…...

Profibus DP主站转Modbus RTU/TCP网关接艾默生流量计与上位机通讯
Profibus DP主站转Modbus RTU/TCP网关接艾默生流量计与上位机通讯 艾默生流量计与Profibus DP主站转Modbus RTU/TCP网关的通讯,是现代工业自动化中的一个关键环节。为了实现这一过程,我们需要了解一些基础概念和具体操作方法。 在工业自动化系统中&…...
promise的说明
目录 1.说明 2.创建promise 3.处理promise结果 4.promise的链式调用 5.静态方法 6.错误处理及误区 7.then() 内部进行异步操作时,需返回新的 Promise 8.promise链式调用控制异步方法的执行顺序 9.总结 1.说明 Promise 是 JavaScript 中处理异步操作的核心对…...
Pass-the-Hash攻击原理与防御实战指南
当黑客说出"我知道你的密码"时,可能连他们自己都不知道你的真实密码。在Windows系统的攻防战场上,Pass-the-Hash(哈希传递攻击)就像一把可以复制的万能钥匙——攻击者不需要知道密码明文,仅凭密码的…...

Linux proc文件系统 内存影射
文章目录 常见的内存分配函数/proc/pid/ 目录解析 用户进程的内存空间分配算法mmap 分配大内存可能不在堆中换为 malloc 现象相同 常见的内存分配函数 malloc / calloc / realloc(来自 C 标准库) void *malloc(size_t size):分配 size 字节…...

五、Hadoop集群部署:从零搭建三节点Hadoop环境(保姆级教程)
作者:IvanCodes 日期:2025年5月7日 专栏:Hadoop教程 前言: 想玩转大数据,Hadoop集群是绕不开的一道坎。很多小伙伴一看到集群部署就头大,各种配置、各种坑。别慌!这篇教程就是你的“救生圈”。 …...