数据结构与算法分析(六)——C++实现二叉查找树
二叉树的基本概念
1.定义
二叉树(binary tree)是一颗树,其中每个节点都不能有多于两个的儿子。
2.实现
每一个节点用一个结构体表示,包含一个关键字和两个指向左儿子和右儿子的指针。
3.遍历方式
中序遍历:左 节点 右
后序遍历:左 右 节点
先序遍历:节点 左 右
4.二叉查找树的概念
一颗二叉树,对于每一个节点X,它的左子树中所有的关键字值都小于X的关键字值,它的右子树中所有的关键字值都大于X的关键字值。
5.二叉查找树的性质
平均深度O(logN)
二叉查找树各种操作的代码实现
用到了很多的递归操作,且所有操作都需要传入操作的节点(即可以对子树进行操作)
1.清空树
算法实现步骤:
1.递归删除左子树
2.递归删除右子树
3.删除该节点,返回一个NULL指针(释放内存后指针依旧指向该段内存,但是内容不确定了)
/***@name Make_empty:递归删除该节点以及该节点下所有的子树*@param1 T:指向该节点的指针*@ret:将NULL返回给删除的该节点
**/
Search_Tree Binary_Tree::Make_empty(Search_Tree T )
{//这里使用了递归删除if(T!=NULL){Make_empty(T->left);Make_empty(T->right);delete T;T=NULL;}return T;
}
2.查找最大(最小值)
算法实现步骤:
1.由二叉查找树的结构决定,找到最左边的叶(最小值),找到最右边的叶(最大值)
2.这里也利用递归去找,为最小值为例,直到找到的节点的左儿子为空时,将该节点返回
注:
这里在递归调用Find_Min时需要加return,否则从堆栈pop出来的时候就只有一个ret,可能会出现问题
/***@name Find_Max:找到该节点的子树中最大的那个值*@param1 T:传入的树节点 如果要找整根树中最大的值则输入root*@ret:指向存最大值的树节点 为子树中最右边的叶
**/
Search_Tree Binary_Tree::Find_Max(Search_Tree T)
{if(T==NULL)return NULL;if(T->right==NULL){return T;}else{return Find_Max(T->right);}
}/***@name Find_Max:找到该节点的子树中最小的那个值*@param1 T:传入的树节点 如果要找整根树中最小的值则输入root*@ret:指向存最大值的树节点 为子树中最左边的叶
**/
Search_Tree Binary_Tree::Find_Min(Search_Tree T)
{if(T==NULL){return NULL;}if(T->left==NULL){return T;}else{return Find_Min(T->left);}
}
3.查找关键字匹配的节点
算法实现步骤:
1.从某一节点向下,如果查询的关键字大于该节点的关键字,到右子树中递归查找,如果查询的关键字小于该节点的关键字,到左子树中递归查找。
2.如果递归到节点已空,则没有找到;如果找到则返回该节点的地址。
注:
在递归Find_Position前也要加return
/***@name Find_Position:查找关键字所在的树的节点*@param1 data:需要匹配的关键字*@param2 T:从哪一个节点开始往下找 只会向下查找*@ret:指向匹配到关键字的节点的指针 没有找到则返回NULL
**/
Search_Tree Binary_Tree::Find_Position(int data,Search_Tree T)
{if(T==NULL){return NULL; }//如果数据比该节点的关键字小的话,查找去左子树中查找if(T->data>data){return Find_Position(data,T->left); }//如果数据比该节点的关键字大的话,查找去右子树中查找else if(T->data<data){return Find_Position(data,T->right);}else{return T;}
}
4.插入节点
由于二叉查找树的结构,插入永远会在叶上,故方便很多
算法实现步骤:
1.根据新插入的节点的关键字大小,在给定节点的左子树递归插入或右子树递归插入
2.直到递归到空节点,new一个节点,然后return该地址
3.最后返回插入完成了的给定节点的地址
/***@name Insert:在树的合适位置插入关键字为data的节点*@param1 data:插入的数据*@param2 T:在该节点的子树中插入数据
**/
Search_Tree Binary_Tree::Insert(int data,Search_Tree T)
{//递归到空节点 这时建立一个新节点if(T==NULL){T=new Tree_node;T->data=data;T->left=T->right=NULL;return T;}//插入的数据小于此时节点的数据,往左插(别忘了赋值给子左节点,指针形参改变不了传入的参数,即虽然T->left新建了一个节点,但此时只有形参指向它)if(T->data>data){T->left=Insert(data,T->left);}//插入的数据大于此时节点的数据,往右插else if(T->data<data){T->right=Insert(data,T->right);}//如果插入的数据等于此时节点的数据,直接返回该节点else{cout<<"can't insert the same data"<<endl;}return T;
}
5.删除某一关键字对应的节点
算法实现步骤:
1.关键字小于给点节点关键字去左子树删,关键字大于给点节点关键字去右子树删。
2.如果关键字等于当前节点了分三种情况删:
(1)当前节点为叶,直接delete,返回NULL;
(2)当前节点只挂一侧有子树,则先用定义中间指针变量temp指向该节点,然后delete当前节点,然后返回其右子树;
(3)当前节点两侧都有子树,则取出右子树中的min节点,将此关键字赋给当前节点,然后递归删除min节点;
3.如果找到空节点了还没找到就报错。
/***@name Delete:删除关节字为data的元素*@param1 data:关键字*@param2 T:从该节点以下的树中删除
**/
Search_Tree Binary_Tree::Delete(int data,Search_Tree T)
{Search_Tree temp;if(T==NULL)cout<<"error:without element to delete"<<endl;else if(T->data<data)T->right=Delete(data,T->right);else if(T->data>data)T->left=Delete(data,T->left);else{//此时data等于T->datatemp=T;if((T->left==NULL)&&(T->right==NULL)) //此时的节点为叶 {delete T;T=NULL;}else{if(T->left==NULL) //此时的左儿子为空,只有右子树{T=T->right; //将T指向右儿子节点delete temp; //释放该节点的内存temp=NULL;}else if(T->right==NULL) //此时的右儿子为空,只有左子树{T=T->left; //将T指向左儿子节点delete temp; //释放该节点的内存temp=NULL;}else //此时既存在左子树又存在右子树{temp=Find_Min(T->right); //找到右子树中最小的节点T->data=temp->data; //将该节点的元素赋给当前节点T->right=Delete(temp->data,T->right); //对右子树进行一次删除操作}}}return T;
}
对递归和指针理解的还不够,搞在一起就开始糊涂了。。。
注:
为什么这里的形参指针不能改变传入的指针的值?
解:
1.改变形参指针指向的内容对传入的指针毫无影响,因为调用完后就消失了
2.这里由于递归带来的混淆,我一直以为形参指针和传入的指针指向的一直是同一块内存,这里举最简单的一个例子,传入的指针指向NULL,形参做出判断,新建了一块内存并指向它,而传入的指针依旧是NULL。
数据结构与算法分析(六)——C++实现二叉查找树相关推荐
- 数据结构与算法分析(十六)--- 如何设计更高效的字符串匹配算法?(BF + RK + KMP + BMH)
文章目录 一.Brute Force 匹配算法 二.Rabin–Karp 匹配算法 三.Knuth–Morris–Pratt 匹配算法 四.Boyer-Moore-Horspool 匹配算法 五.字符 ...
- 数据结构与算法分析(C++版)(第二版)
查看书籍详细信息: 数据结构与算法分析(C++版)(第二版) 内容简介 本书采用程序员最爱用的面向对象C++语言来描述数据结构和算法,并把数据结构原理和算法分析技术有机地结合在一起,系统介绍了各种类型 ...
- 20172326 《程序设计与数据结构》第六周学习总结
学号 20172326 <程序设计与数据结构>第六周学习总结 教材学习内容总结 非线性数据结构--树 结点:结点分为根节点,内部结点.根据结点分为parent和children,结点之上为 ...
- 数据结构和算法分析学习笔记(三)--二叉查找树的懒惰删除(lazy deletion)
这次的问题来自<数据结构与算法分析(C++描述)>的习题4.16,如下: -------------------------- 4.16 重做二叉查找树类以实现懒惰删除.注意,这将影响所 ...
- 《数据结构与算法分析》课程设计——迷宫问题
中国矿业大学信控学院 补一下我之前在博客园发布的内容 懒得调了,想复制完整代码直接复制最下面的,想复制分布代码去看我博客园链接吧 <数据结构与算法分析>课程设计--迷宫问题 - 刷子 ...
- 数据结构与算法分析 作业讲解文档目录
参考教材:<数据结构(C语言版 第2版)> 严蔚敏,李冬梅,吴伟民编著,人民邮电出版社,2022年版. 对应的作业题讲解视频: 数据结构与算法分析作业讲解视频合集https://ww ...
- s数据结构替换子表java版_数据结构与算法分析Java语言描述(第3版) PDF和源码免费 下载...
<数据结构与算法分析Java语言描述(第3版)>PDF和源码免费 下载 免积分下载 用户下载说明: 图书简介: 数据结构:Java语言描述(原书第3版)是国外数据结构与算法分析方面的经典教 ...
- 20162303 2016-2017-2 《程序设计与数据结构》第六周学习总结
20162303 2016-2017-2 <程序设计与数据结构>第六周学习总结 教材学习内容总结 通过继承来创建类,比从零开始编写代码来的更快.更容易也更经济. 继承在父类与子类之间建立了 ...
- Weiss的数据结构与算法分析(C++版)源码编译说明
最近尝试编译Weiss的那本数据结构与算法分析(C++版)提供的源代码时,遇到一些问题,特记录如下: 考虑到该书提供的代码是使用模板技术较多,这在提供简洁代码的同时,也给源码的编译带来了一些问题.因而 ...
- 数据结构与算法分析c++第四版_研分享 | 人工智能学院数据结构与算法分析考研备考整理...
数据结构与算法分析 1.在顺序表中插入或删除一个元素,需要平均移动(表中一半)元素,具体移动的元素个数与(表长和该元素在表中的位置)有关. 2.如果有两个数,每个数的所有约数(除它本身以外)的和正好等 ...
最新文章
- Opensmile 简介
- wget安装Jenkins
- 【编译原理】文法分类
- SpringBoot 中 4 大核心组件,你了解多少?
- Visual Studio 2010如何利用宏
- 报告节选2:桌面虚拟化需重视网络和存储
- Java jar 包免费下载(全)
- PowerDesigner导出rtf文件
- c语言编写cad建筑画图程序,CAD建筑平面图绘图步骤试题.doc
- 从零做一个小程序(计算器)赚钱
- Qt编程(一) Qt框架简介
- ffmpeg 视频裁剪格式问题
- Python入门技巧
- [计蒜客][递归]阿克曼函数
- Java学习(58)Java单例模式——单例模式的特点及适用场景
- 致我那终将逝去的青春——小二的原创经典
- java jms clust,activeMQ使用总结 (集群方案)
- matplotlib之pyplot模块——绘制箱线图(盒须图)boxplot()(二)演示外观参数、返回值
- windows永久关闭快速编辑模式
- python计算机二级含金量-计算机二级证书含金量到底有多高?你真的知道吗?
热门文章
- oracle 内部表连接方式,ORACLE 表连接方式
- 实现微信小程序和支付宝小程序二维码合并
- mysql5.7.11源码安装,mysql 5.7.11 源码安装
- Flink java作为消费者连接虚拟机中的kafka/或本地的kafka,并解决java.net.UnknownHostException报错
- java arraylist排序_一文读懂Java集合框架
- 漫谈CGI FastCGI WSGI
- mongodb4简明笔记
- UVA5876 Writings on the Wall 扩展KMP
- Installation error: INSTALL_FAILED_UID_CHANGED
- realloc() 用法详解