数据结构--树和二叉树

devtools/2024/9/22 10:53:10/

目录

一.树概念及结构(了解) 

1.1树的概念 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它 叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

有一个特殊的结点,称为根结点,根节点没有前驱结点。

除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集 合Ti(1又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以 有0个或多个后继。

因此,树是递归定义的。(常用递归思想建立树)

二.树的实现

三.实现树的函数

1. NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右 子树之前。

2. LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中 (间)

 3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

 4. 求二叉树所有节点的个数.

5. 求叶子节点的个数.

6.销毁函数.


一.树概念及结构(了解)

1.1树的概念 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它 叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
有一个特殊的结点,称为根结点,根节点没有前驱结点。
除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集 合Ti(1又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以 有0个或多个后继。
因此,树是递归定义的。(常用递归思想建立树)

二.树的实现

这段代码是用 C 语言定义了一个二叉树的数据结构。 
一、结构定义
1.  typedef char BTDataType; :这里定义了一个别名 BTDataType ,代表二叉树节点存储的数据类型为字符型。
2.  typedef struct BinaryTreeNode :定义了一个结构体类型 BinaryTreeNode ,这个结构体代表二叉树的节点。
-  struct BinaryTreeNode* left; :指向左子树的指针。
-  struct BinaryTreeNode* right; :指向右子树的指针。
-  BTDataType data; :存储节点的数据,这里是字符型数据。
通过这个定义,可以方便地创建二叉树的节点,并构建二叉树的数据结构,用于存储和操作二叉树中的数据。

//定义二叉树
typedef char BTDataType;
typedef struct BinaryTreeNode
{struct BinaryTreeNode* left;struct BinaryTreeNode* right;BTDataType data;
}BTNode;

三.实现树的函数

前序/中序/后序的递归结构遍历:是根据访问结点操作发生位置命名

1. NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右 子树之前。

这段 C 语言代码实现了二叉树的前序遍历。
一、函数功能
 PrevOrder 函数用于对给定的二叉树进行前序遍历。前序遍历的顺序是先访问根节点,再遍历左子树,最后遍历右子树。
二、实现步骤 
1. 首先判断根节点是否为 NULL 。如果是,则输出 "NULL " 表示该节点为空,并直接返回。这是为了处理空树的情况。
2. 如果根节点不为空,则先输出根节点的数据 root->data 。
3. 接着递归调用 PrevOrder 函数遍历左子树 root->left 。
4. 最后递归调用 PrevOrder 函数遍历右子树 root->right 。
通过这样的递归调用,就可以按照前序遍历的顺序输出二叉树中所有节点的数据。如果二叉树为空树,则输出 "NULL " 来表示。

//前序
void PrevOrder(BTNode* root)
{if (root == NULL) {printf("NULL ");return;}printf("%c ", root->data);PrevOrder(root->left);PrevOrder(root->right);
}

2. LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中 (间)

这段 C 语言代码实现了二叉树的中序遍历。
 一、函数功能
 InOrder 函数用于对给定的二叉树进行中序遍历。中序遍历的顺序是先遍历左子树,再访问根节点,最后遍历右子树。
二、实现步骤
1. 首先判断根节点是否为 NULL 。如果是,则输出 "NULL " 表示该节点为空,并直接返回。这是为了处理空树的情况。
2. 如果根节点不为空,则先递归调用 InOrder 函数遍历左子树 root->left 。
3. 接着输出根节点的数据 root->data 。
4. 最后递归调用 InOrder 函数遍历右子树 root->right 。
通过这样的递归调用,就可以按照中序遍历的顺序输出二叉树中所有节点的数据。如果二叉树为空树,则输出 "NULL " 来表示。

//中序
void InOrder(BTNode* root)
{if (root == NULL) {printf("NULL ");return;}InOrder(root->left);printf("%c ", root->data);InOrder(root->right);
}

 3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

这段 C 语言代码实现了二叉树的后序遍历。
 一、函数功能
 PostOrder 函数用于对给定的二叉树进行后序遍历。后序遍历的顺序是先遍历左子树,再遍历右子树,最后访问根节点。
二、实现步骤
1. 首先判断根节点是否为 NULL 。如果是,则输出 "NULL " 表示该节点为空,并直接返回。这是为了处理空树的情况。
2. 如果根节点不为空,则先递归调用 PostOrder 函数遍历左子树 root->left 。
3. 接着递归调用 PostOrder 函数遍历右子树 root->right 。
4. 最后输出根节点的数据 root->data 。
通过这样的递归调用,就可以按照后序遍历的顺序输出二叉树中所有节点的数据。如果二叉树为空树,则输出 "NULL " 来表示。

//后序
void PostOrder(BTNode* root)
{if (root == NULL) {printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%c ", root->data);
}

 4. 求二叉树所有节点的个数.

这段 C 语言代码实现了求二叉树所有节点个数的功能。 
一、函数功能
 TreeSize 函数用于计算给定二叉树的节点总数。
二、实现思路
利用后序遍历的思想,先分别计算左子树和右子树的节点个数,再加上根节点(值为 1),得到整个二叉树的节点个数。
1. 首先判断根节点是否为 NULL 。如果是,则表示这是一棵空树,节点个数为 0,直接返回 0。
2. 如果根节点不为空,则递归计算左子树的节点个数 TreeSize(root->left) 。
3. 接着递归计算右子树的节点个数 TreeSize(root->right) 。
4. 最后将左子树节点个数、右子树节点个数与根节点(值为 1)相加,即 TreeSize(root->left) + TreeSize(root->right) + 1 ,并返回这个值作为整个二叉树的节点个数。

//求二叉树所有节点的个数
//可以遍历,这里利用后序的思想求解
int TreeSize(BTNode* root)
{return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

5. 求叶子节点的个数.

这段 C 语言代码实现了计算二叉树中叶子节点个数的功能。
一、函数功能
 TreeLeafSize 函数用于确定给定二叉树中的叶子节点数量。
二、实现思路
1. 首先判断根节点是否为 NULL 。如果是,则表示这是一棵空树,没有叶子节点,直接返回 0。
2. 如果根节点不为空,接着判断该节点是否为叶子节点,即判断其左子树和右子树是否都为 NULL 。如果是叶子节点,则返回 1。
3. 如果不是叶子节点,则分别递归计算左子树中的叶子节点个数 TreeLeafSize(root->left) 和右子树中的叶子节点个数 TreeLeafSize(root->right) ,然后将这两个值相加并返回,从而得到整个二叉树的叶子节点个数。

// 叶子节点的个数
int TreeLeafSize(BTNode* root)
{if (root == NULL)return 0;if (root->left == NULL && root->right == NULL)return 1;return TreeLeafSize(root->left)+ TreeLeafSize(root->right);
}

6.销毁函数.

这段 C 语言代码实现了销毁二叉树的功能。
一、函数功能
 DestoryTree 函数用于释放给定二叉树所占用的内存空间,实现二叉树的销毁。
二、实现思路
采用后序遍历的方式,先递归销毁左子树和右子树,最后释放根节点的内存并将根节点指针置为 NULL ,以防止悬空指针。
1. 首先判断根节点是否为 NULL 。如果是,则直接返回,因为空树无需销毁。
2. 如果根节点不为空,则先递归调用 DestoryTree 函数销毁左子树 root->left 。
3. 接着递归调用 DestoryTree 函数销毁右子树 root->right 。
4. 当左子树和右子树都被销毁后,使用 free(root) 释放根节点所占用的内存空间。
5. 最后将根节点指针置为 NULL ,防止出现悬空指针。这样就完成了整个二叉树的销毁。

//如果要摧毁的话,参数需要结构体指针的地址
void DestoryTree(BTNode* root)
{if (root = NULL)return;DestoryTree(root->left);DestoryTree(root->right);free(root);root = NULL;
}

http://www.ppmy.cn/devtools/115426.html

相关文章

【JAVA开源】基于Vue和SpringBoot的在线文档管理系统

本文项目编号 T 038 ,文末自助获取源码 \color{red}{T038,文末自助获取源码} T038,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

Java项目实战II基于Java+Spring Boot+MySQL的大型商场应急预案管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在快节奏的…

go语言的基本语法

学了go语言但是一直没整理。。。那怎么证明我学了?如果学了之后忘了怎么复习?遂诞生这几篇,当作Linux中间的小插曲 整理一下go语言的基本语法: package mainimport ("bufio""fmt""os" ) 在使用对…

外包干了4年,技术退步太明显了。。。。。

先说一下自己的情况,本科生生,20年通过校招进入武汉某软件公司,干了差不多4年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能…

发票OFD格式转换成PDF

引入依赖&#xff0c;低版本的报错&#xff0c;2.0.2能够实现转换 <dependency><groupId>org.ofdrw</groupId><artifactId>ofdrw-converter</artifactId><version>2.0.2</version><exclusions><exclusion><groupId&g…

微信小程序04-常用API上

零、文章目录 微信小程序04-常用API上 1、案例&#xff1a;音乐播放器 &#xff08;1&#xff09;案例分析 需求&#xff1a;“音乐播放器”微信小程序可以让用户随时随地享受音乐&#xff0c;给用户带来了便捷的音乐体验&#xff0c;且支持后台播放&#xff0c;用户可以在…

VisualPromptGFSS

COCO-20 i ^i i太大&#xff0c;不建议复现

springMvc的初始配置

基础文件结构(toWeb插件) 1.导入对应依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"ht…