【数据结构】树,二叉树,满二叉树,完全二叉树的定义和二叉树的基本操作

news2024/11/24 6:05:31

🎊专栏【数据结构】

🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。

🎆音乐分享【勋章】

大一同学小吉,欢迎并且感谢大家指出我的问题🥰

目录

⭐树

🏳️‍🌈定义

 🏳️‍🌈注意

🍔树的基本术语

⭐二叉树

🏳️‍🌈定义

🎆二叉树和树的区别

🏳️‍🌈二叉树的性质

⭐满二叉树

⭐完全二叉树

🎁遍历二叉树

🎈先序遍历二叉树

🎈中序遍历二叉树

🎈后序遍历二叉树

🎁构建二叉树

🎈算法步骤

🎈代码

🎁复制二叉树

🎈算法步骤

🎈代码

🎁计算二叉树的深度

🎈算法步骤

🎈代码

🎁统计二叉树中结点的总数

🎈算法步骤

🎈代码

🎁统计二叉树中叶子结点的个数

🎈算法步骤

🎈代码

🎊完整代码 


 

⭐树

🏳️‍🌈定义

树是n(n>=0)个结点的有限集

n=0:称为空树

n>0:称为非空树

✨对于非空树,有下面两个特点

(1)有且只有一个称为根的结点

(2)除根节点之外的其余结点可以分为m(m>0)个互不相交的有限集,对于每一个有限集本身又是一棵树,并且称为根的子树

树可以有多种表示方法,如下图所示 

 🏳️‍🌈注意

如下图所示

 

🍔树的基本术语

结点:树的一个独立单元(比如上图的ABCD)

结点的度:结点拥有的子树(比如上图中,A的度为3,B的度为2)

树的度:树内各结点度的最大值(比如上图的树的度为3)

叶子(终端结点):度为0的结点

层次:结点的层次从根开始定义,根为第一层,根的孩子为第二层

树的深度(高度):树中结点的最大层次

森林:m棵互不相交的树的集合。对于树的每个结点而言,其子树的集合就是森林

⭐二叉树

🏳️‍🌈定义

树是n(n>=0)个结点的有限集

n=0:称为空树

n>0:称为非空树

✨对于非空树,有下面两个特点

(1)有且只有一个称为根的结点

(2)除根节点之外的其余结点可以分为2个互不相交的子集,分别称为T的左子树T1和右子树T2,且T1T2都是二叉树

🎆二叉树和树的区别

🚥二叉树中不存在度>2的结点🚥

二叉树的左右子树有左右之分,不能随意颠倒


二叉树也有多种表示方法,如下图所示

 

🏳️‍🌈二叉树的性质

🎈第i层上至多有2^(i-1)(i>=1)个结点

🎈深度为k的二叉树至多有2^k-1(k>=1)个结点

🎈对于任何一颗二叉树T,如果其终端结点树为n0,度为2的结点树为n2

那么n0=n2+1

⭐满二叉树

深度为k且有2^k-1个结点的二叉树,每一层的结点数都是最大结点数

⭐完全二叉树

 

深度为k,有n个结点的二叉树,当且仅当每一个结点都与深度为k的满二叉树 中编号从1到n的结点一一对应时,为完全二叉树


文末有完整代码


 

🎁遍历二叉树

🎆定义

typedef struct BiNode{				
    char data;
    struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

🎈先序遍历二叉树

操作定义如下:若二叉树为空,则操作为空;否则
(1)访问根结点;
(2)先序遍历左子树;
(3)先序遍历右子树。

void preorder_traversal(BiTree root) {
    if (!root) {
        return;
    }

    cout << root->data << " "; // 访问根节点
    preorder_traversal(root->lchild); // 递归访问左子树
    preorder_traversal(root->rchild); // 递归访问右子树
}


🎈中序遍历二叉树

操作定义如下:若二叉树为空,则操作为空;否则
(1)中序遍历左子树;
(2)访问根结点;
(3)中序遍历右子树。

void inorder_traversal(BiTree root) {
    if (!root) {
        return;
    }

    inorder_traversal(root->lchild); // 递归访问左子树
    cout << root->data << " "; // 访问根节点
    inorder_traversal(root->rchild); // 递归访问右子树
}

🎈后序遍历二叉树

操作定义如下:若二叉树为空,则操作为空;否则
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问根结点;

void postorder_traversal(BiTree root) {
    if (!root) {
        return;
    }

    postorder_traversal(root->lchild); // 递归访问左子树
    postorder_traversal(root->rchild); // 递归访问右子树
    cout << root->data << " "; // 访问根节点
}

🎁构建二叉树

法一:

比如根据  ABC##DE#G##F###  这一段来构建

🎈算法步骤

1.读取字符序列,读入字符ch

2.如果ch是“#”,表明该二叉树为空树,即T为NULL,否则执行下面的操作

(1)申请一个内存空间T

(2)将ch赋给T->data

(3)递归创建T的左子树

(4)递归创建T的右子树

🎈代码

void CreateBiTree(BiTree &T){	
	
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			
	else{							
		T=new BiTNode;
		T->data=ch;					//生成根结点
		CreateBiTree(T->lchild);	//递归创建左子树
		CreateBiTree(T->rchild);	//递归创建右子树
	}								
}					

法二:

 // 构建二叉树
    BiTree root = new BiNode{'A', nullptr, nullptr};
    root->lchild = new BiNode{'B', nullptr, nullptr};
    root->lchild->lchild = new BiNode{'C', nullptr, nullptr};
    root->lchild->rchild = new BiNode{'D', nullptr, nullptr};
    root->lchild->rchild->lchild = new BiNode{'E', nullptr, nullptr};
    root->lchild->rchild->lchild->rchild = new BiNode{'G', nullptr, nullptr};
    root->lchild->rchild->rchild = new BiNode{'F', nullptr, nullptr};

🎁复制二叉树

🎈算法步骤

1.为空树,递归结束

2.不为空树,那么执行下面的操作

(1)申请一个新结点空间,复制根节点

(2)递归复制左子树

(3)递归复制右子树

🎈代码

void Copy(BiTree T,BiTree &NewT)
{
	if(T==NULL){
		NweT=NULL;
		return;
	}else{
		NewT=new BiTree;		//复制根节点
		NewT->data=T->data;
		Copy(T->lchild,NewT->lchild);
		Copy(T->rchild,NewT->rchild);
	}
}

🎁计算二叉树的深度

🎈算法步骤

1.为空树,递归结束

2.不为空树,那么执行下面的操作

(1)递归计算左子树的深度为m

(2)递归计算右子树的深度为n

(3)如果m>n,那么二叉树深度为m+1,否则为n+1

🎈代码

int Depth(BiTree T)
{ 
	int m,n;
	if(T == NULL ) return 0;        //如果是空树,深度为0,递归结束
	else 
	{							
		m=Depth(T->lchild);			//递归计算左子树的深度记为m
		n=Depth(T->rchild);			//递归计算右子树的深度记为n
		if(m>n) return(m+1);		//二叉树的深度为m 与n的较大者加1
		else return (n+1);
		//+1,所以可以计算出来
	}
}

🎁统计二叉树中结点的总数

🎈算法步骤

如果是空树,那么结点个数为0,递归结束

否则,结点个数=左子树结点个数+右子树结点个数+1

🎈代码

int NodeCount(BiTree T)
{
     if(T==NULL) return 0;  			// 如果是空树,则结点个数为0,递归结束
     else return NodeCount(T->lchild)+ NodeCount(T->rchild) +1;
     //否则结点个数为左子树的结点个数+右子树的结点个数+1
     
     //+1,所以可以计算出来//
} 

🎁统计二叉树中叶子结点的个数

🎈算法步骤

如果是空树,那么结点个数为0,递归结束

否则,遍历到NULL,即叶子节点

🎈代码

int LeafCount(BiTree T){
 	if(T==NULL) 	//如果是空树返回0
		return 0;
	if (T->lchild == NULL && T->rchild == NULL)
		return 1; //如果是叶子结点返回1
		
		// 1,所以可以计算出来
		
	else return LeafCount(T->lchild) + LeafCount(T->rchild);
}

🎊完整代码 

#include<iostream>
using namespace std;
typedef struct BiNode{				
	char data;
	struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;


void CreateBiTree(BiTree &T){	
	
	char ch;
	cin >> ch;
	if(ch=='#')  T=NULL;			
	else{							
		T=new BiTNode;
		T->data=ch;					//生成根结点
		CreateBiTree(T->lchild);	//递归创建左子树
		CreateBiTree(T->rchild);	//递归创建右子树
	}								
}									


void PreOrderTraverse(BiTree T)
{  
   if (T) {
      cout<<T->data;            // 访问结点
      PreOrderTraverse(T->lchild); // 遍历左子树
      PreOrderTraverse(T->rchild);// 遍历右子树  
   }
}



void InOrderTraverse(BiTree T){  
	
	if(T){
		InOrderTraverse(T->lchild);
		cout << T->data;
		InOrderTraverse(T->rchild);
	}
}


void PostOrderTraverse(BiTree T)
{ 
   if (T) {
      PostOrderTraverse(T->lchild); // 遍历左子树
      PostOrderTraverse(T->rchild);// 遍历右子树
      cout << T->data;           // 访问结点
    }
}



int NodeCount(BiTree T)
{
     if(T==NULL) return 0;  			// 如果是空树,则结点个数为0,递归结束
     else return NodeCount(T->lchild)+ NodeCount(T->rchild) +1;
     //否则结点个数为左子树的结点个数+右子树的结点个数+1
     
     //+1,所以可以计算出来//
} 


//计算二叉树中叶子结点的个数
int LeafCount(BiTree T){
 	if(T==NULL) 	//如果是空树返回0
		return 0;
	if (T->lchild == NULL && T->rchild == NULL)
		return 1; //如果是叶子结点返回1
		
		// 1,所以可以计算出来
		
	else return LeafCount(T->lchild) + LeafCount(T->rchild);
}


//计算二叉树的深度	
int Depth(BiTree T)
{ 
	int m,n;
	if(T == NULL ) return 0;        //如果是空树,深度为0,递归结束
	else 
	{							
		m=Depth(T->lchild);			//递归计算左子树的深度记为m
		n=Depth(T->rchild);			//递归计算右子树的深度记为n
		if(m>n) return(m+1);		//二叉树的深度为m 与n的较大者加1
		else return (n+1);
		//+1,所以可以计算出来
	}
}

int main(){
	BiTree tree;
	int nodecount=0,leafcount=0,depth=0;
	cout<<"请输入建立二叉链表的序列:\n";
	CreateBiTree(tree);
	cout<<endl;
	cout<<"先序遍历的结果为:\n";
	PreOrderTraverse(tree);
	cout<<endl;
	cout<<"中序遍历的结果为:\n";
	InOrderTraverse(tree);
	cout<<endl;
	cout<<"后序遍历的结果为:\n";
	PostOrderTraverse(tree);
	cout<<endl;
	cout<<"该二叉树中结点总数为:";
	cout<<NodeCount(tree)<<endl;
	cout<<"该二叉树中叶子结点总数为:";
	cout<<LeafCount(tree)<<endl;
	cout<<"该二叉树的深度为:";
	cout<<Depth(tree)<<endl;
	return 0;
}

🥰如果大家有不明白的地方,或者文章有问题,欢迎大家在评论区讨论,指正🥰 

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

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

相关文章

祝贺!Coremail连续4年入选中国网络安全市场全景图

5月16日&#xff0c;数说安全正式发布《2023年中国网络安全市场全景图》&#xff08;以下简称“全景图”&#xff09;。作为国内头部电子邮件产品与解决方案提供商&#xff0c;Coremail凭借着出色的产品技术和服务&#xff0c;连续4年入选“邮件安全”领域&#xff0c;体现行业…

计算机视觉 day 93 学习像素级膨胀滤波的高效率单图像去噪

学习像素级膨胀滤波的高效率单图像去噪 1 Introduction3 Methodology3.1 逐像素图像滤波解调3.2 可学习像素级膨胀滤波Kernel prediction network&#xff08;核预测网络&#xff09;Multi-dilated image filtering and fusion&#xff08;多扩张图像滤波与融合&#xff09; 3.…

基础篇007. 串行通信(一)--阻塞方式发送接收

目录 1. 串行通信 1.1 串行通信概述 1.2 串行通信协议 2. 实验任务 3. 硬件原理 4. 利用STM32CubeMX创建MDK工程 4.1 STM32CubeMX工程创建 4.2 配置调试方式 4.4 配置GPIO 4.5 配置串口参数 4.6 配置时钟 4.7 项目配置&#xff1a; 4.8 串口初始化程序说明 5. 串行…

机器学习笔记 - 利用自动编码器神经网络构建图像去噪器

一、概述 传统的图像噪声去除主要是基于各种滤波器,但它们不是特定于数据的,因此可能会损失很多图像的细节,或者噪声去除的效果不是很理想。基于神经网络的自动编码器可以用于学习数据集的噪声去除滤波器。 关于自动编码器的介绍,可以参考下面的链接。https://skydance.blo…

Windows Server 2019 中文版、英文版下载 (updated May 2023)

Windows Server 2019 Version 1809&#xff0c;2023 年 5 月更新 请访问原文链接&#xff1a;https://sysin.org/blog/windows-server-2019/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 本站将不定期发布官方原版风格月度更…

nest笔记十一:一个完整的nestjs示例工程(upgrade)

概述 链接&#xff1a;upgrade 相关文章列表 nestjs系列笔记 示例工程说明 这个工程是我使用nestjs多个项目后&#xff0c;总结出来的模板。这是一个完整的工程&#xff0c;使用了yaml做为配置&#xff0c;使用了log4js和redis和typeorm&#xff0c;sawgger&#xff0c;自…

ChatGPT热门资料汇总,绝对不割韭菜

前言 ChatGPT 的出现&#xff0c;AI圈子一下就热闹起来了&#xff0c;各个公司争先恐后地出自己的产品&#xff0c;百度的文心一言、谷歌的Bard、阿里的通义千问等等&#xff0c;有很多人借此机会已经赚到百万&#xff0c;很多卖课搞培训的都是互为合伙人&#xff0c;大家都懂…

243亿美元营收背后,百年龙头的汽车生态砝码

伴随着更为显著的全球汽车新能源化、智能化趋势&#xff0c;汽车产业必将迎来更多新机遇。 一方面&#xff0c;主机厂为保持竞争优势、适应客户多元化需求&#xff0c;不断加快汽车更迭速度&#xff0c;为汽车产业带来了新的市场机遇。另一方面&#xff0c;随着人工智能、云计…

2023企业数智化财务创新峰会 · 成都站圆满举办!

5月17日&#xff0c;「智能会计 价值财务」2023企业数智化财务创新峰会巡回来至天府&#xff0c;川大商学院权威教授领衔分享、大型企业财务先锋详解财务数智化领先实践、毕马威资深专家现场解读财务创新趋势与典型案例&#xff0c;与线上线下数千人一同见证“智能会计”新时代…

网络请求--http请求学习详解

写在前面&#xff1a; 文章目录 http简介http报文格式请求样例响应样例 起始头格式 常见请求方法GETPOSTRESTful风格 头部字段Content-Type Https http简介 http&#xff1a;超文本传输协议 是一种无状态&#xff0c;无连接&#xff0c;以应答式的协议&#xff0c;可使用扩展…

力扣sql中等篇练习(二十三)

力扣sql中等篇练习(二十三) 1 统计实验的数量 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 有可能数据本身就不全,就需要自行创建临时表 WITH T as (SELECT Android p1,Reading e1UNIONSELECT Android p1,Sports e1UNIONSELECT Android p1,Prog…

最简单配置jenkins容器使用宿主机的docker方法

构建镜像和发布镜像到harbor都需要使用到docker命令。而在Jenkins容器内部安装Docker官方推荐直接采用宿主机带的Docker即可 设置Jenkins容器使用宿主机Docker 设置宿主机docker.sock权限 chown root:root /var/run/docker.sock chmod orw /var/run/docker.sock 添加数据卷 v…

215.数组中第 k 个最大的元素。

解题思路&#xff1a; 利用快排的思想&#xff0c;不断地将数组分成若干部分&#xff0c;缩小查找范围&#xff0c;最终找到第 k 大的元素。 1、首先&#xff0c;对数组进行快速排序&#xff0c;使得数组从大到小排序&#xff0c;然后返回排序后的第 k 个元素即可。 2、在快排…

关于window.print打印分页功能

平常window.print分页一般打印时用到page-break-after:always; 打印的样式设置在 <style type"text/css" media"print"></style>进行设置 但现在我想动态打印分页&#xff0c;即内容一页时打印一页&#xff0c;内容两页时打印两页。。。 现…

HBase 写入数据(Scala代码)

代码如下》》 package Flink_HBase_APLimport org.apache.hadoop.hbase.{HBaseConfiguration, TableName} import org.apache.hadoop.hbase.client.{ConnectionFactory, Put} import org.apache.hadoop.hbase.util.Bytesobject this_one {def main(args: Array[String]): Unit…

开源即时通讯IM框架MobileIMSDK的Uniapp端开发快速入门

► 相关链接&#xff1a; ① MobileIMSDK-Uniapp端的详细介绍② MobileIMSDK-Uniapp端的开发手册new&#xff08;* 精编PDF版&#xff09; 一、理论知识准备 您需要对Uniapp和Vue开发有所了解&#xff1a; 1&#xff09;Uniapp 官方入门教程2&#xff09;可能是最好的 unia…

MyBatis Plus 拦截器实现数据权限控制

一、介绍 上篇文章介绍的MyBatis Plus 插件实际上就是用拦截器实现的&#xff0c;MyBatis Plus拦截器对MyBatis的拦截器进行了包装处理&#xff0c;操作起来更加方便 二、自定义拦截器 2.1、InnerInterceptor MyBatis Plus提供的InnerInterceptor接口提供了如下方法&#x…

SpringCloud 集成 Eureka Server

SpringCloud 集成 Eureka Server 1 pom.xml2 application.yml3 appliction.java4 启动 Eureka的优点&#xff1a; 简单易用&#xff1a;Eureka设计简单&#xff0c;容易上手和部署。 高可用性&#xff1a;Eureka支持高可用性配置&#xff0c;通过使用多个Eureka服务器实例来提…

IEEE Robotics and Automation Letters(RA-L)与ICRA投稿

一 总体感受 RAL不愧未短平快的论文&#xff0c;从接收论文、送审和复审都相当快&#xff0c;我的两个多月出最终接收结果&#xff0c;期刊官网规定6个月内出最终结果。作为现在IEEE主推的短文&#xff0c;限制在8页以内&#xff0c;在6页以上时超页费为175刀/页&#xff0c;目…

平台使用篇 | 批处理(bat)脚本使用教程(二)

导读 BAT脚本提供了一种快速且有效的自动化方式&#xff0c;使用户能够更轻松地处理大量的任务&#xff0c;并且可以根据需要自由地调整和修改脚本。本讲简要介绍了批处理技术及其常用命令。本篇教程主要对批处理技术的语言特点和编程思路进行重点讲解。 RflySim平台更多学习资…