当前位置: 首页 > news >正文

数据结构与算法分析实验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 是树的节点数。中序遍历输出二叉树则是很好的排序方法。通过实验,我们可以更加深入地理解二叉查找树的概念和性质,掌握二叉查找树的常见操作的实现方法。同时,我们也可以通过实验发现一些二叉查找树的应用场景,例如在数据库中的索引结构、文件系统中的目录结构等。需要注意的是,二叉查找树的性能高度依赖于树的平衡性。如果树的平衡性较差,可能会导致搜索效率降低。因此,在实际应用中,需要对二叉查找树进行适当的平衡调整,例如使用红黑树等自平衡二叉查找树。

相关文章:

  • 问题及解决01-面板无法随着窗口的放大而放大
  • 【论文阅读】Efficient and secure federated learning against backdoor attacks
  • Client 和 Server 的关系理解
  • 【AI智能推荐系统】第七篇:跨领域推荐系统的技术突破与应用场景
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月10日第73弹
  • 如何避免在CMD中分段发送问题导致大模型多段回复的问题?
  • 解密数据结构之位图和布隆过滤器
  • 【Redis进阶】持久化
  • 每日算法刷题Day1 5.9:leetcode数组3道题,用时1h
  • [6-2] 定时器定时中断定时器外部时钟 江协科技学习笔记(41个知识点)
  • (四)毛子整洁架构(Presentation层/Authentiacation)
  • 问题解决思路:numpy:DLL load failed
  • QSFP+、QSFP28、QSFP-DD接口分别实现40G、100G、200G/400G以太网接口
  • AUTODL Chatglm2 langchain 部署大模型聊天助手
  • 《用MATLAB玩转游戏开发:从零开始打造你的数字乐园》基础篇(2D图形交互)-《打砖块:向量反射与实时物理模拟》MATLAB教程
  • 【数据结构与算法】图的基本概念与遍历
  • 离线化 Service Worker
  • yocto的大致工作流程
  • [SV]等待32个instance的某一个信号的pulse,该怎么写?
  • 【LeetCode 热题 100】215. 数组中的第K个最大元素(Python 快速选择详解)
  • 经济日报金观平:充分发挥超大规模市场优势
  • 冯德莱恩:欧美贸易谈判前不会前往美国会见特朗普
  • 中俄就应对美加征所谓“对等关税”等问题进行深入交流
  • 央行最新报告:积极落地5月推出的一揽子金融政策,促进经济供需平衡、物价合理回升
  • 三星“七天机”质保期内屏幕漏液被要求自费维修,商家:系人为损坏
  • 河南省省长王凯在郑州调研促消费工作,走访蜜雪冰城总部