【数据结构】二叉树的链式实现及遍历

文章目录

  • 一、二叉树的遍历
    • 1、前序遍历
    • 2、中序遍历
    • 3、后序遍历
    • 4、层序遍历
  • 二、二叉树结点个数及高度
    • 1、二叉树节点个数
    • 2、二叉树叶子节点个数
    • 3、二叉树第k层节点个数
    • 4、二叉树查找值为x的节点
  • 三、二叉树创建及销毁
    • 1、通过前序遍历数组创建二叉树
    • 2、二叉树的销毁
    • 3、判断是否为完全二叉树
  • 四、测试代码

在这里插入图片描述

一、二叉树的遍历

后文所有代码中的二叉树结点:

typedef char BTDataType;
//二叉树结点结构体
typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;

1、前序遍历

前,中,后序遍历都可以采用分治递归的思想解决,将根节点和它的孩子结点分别处理。

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}printf("%c ", root->data);BinaryTreePrevOrder(root->left);BinaryTreePrevOrder(root->right);
}

此处仅利用递归展开图分析前序遍历,中序和后序也是相同的思想:

在这里插入图片描述

在这里插入图片描述

2、中序遍历

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}BinaryTreeInOrder(root->left);printf("%c ", root->data);BinaryTreeInOrder(root->right);
}

3、后序遍历

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}BinaryTreePostOrder(root->left);BinaryTreePostOrder(root->right);printf("%c ", root->data);
}

4、层序遍历

层序遍历需要利用队列来进行,如果二叉树跟结点不为空,则让指向它的一个指针入队,然后将队头结点记录下来,先将它的值打印,然后判断它的左右孩子为非空则入队,然后删掉队头换下一个继续记录打印…直到队列为空则遍历完成。

例如对如图这个二叉树:

层序遍历结果为:12345
在这里插入图片描述
先将根节点1入队,打印1

在这里插入图片描述

然后将1的左右孩子2和3入队
在这里插入图片描述

删掉队头1,front换为2,打印2
在这里插入图片描述

然后将2的左孩子4入队
在这里插入图片描述

删掉队头2,front换为3,打印3
在这里插入图片描述

然后将3的右孩子5入队
在这里插入图片描述

… …

接着按这样打印4,5便完成了二叉树的层序遍历

在这里插入图片描述

程序代码利用了自己创建的队列,代码如下:

//层序遍历
void LevelOrder(BTNode* root)
{//创建队列Que q;QueueInit(&q);//如果根节点不为空,则放进队列if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){//将队头打印BTNode* front = QueueFront(&q);printf("%c ", front->data);//判断front左右节点不为空则入队if (front->left)QueuePush(&q, front->left);if (front->right)QueuePush(&q, front->right);QueuePop(&q);}printf("\n");QueueDestroy(&q);
}

二、二叉树结点个数及高度

1、二叉树节点个数

采用分治法递归实现,当根节点为空时返回值为0,不为空则返回左右子树上的节点数加上自身1。

int BinaryTreeSize(BTNode* root)
{return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

2、二叉树叶子节点个数

采用分治法递归实现,根节点为空时返回0,当根节点没有孩子结点时说明它是叶子节点,返回1,其他情况时只需左右子树上的叶子节点相加即可。

int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL){return 0;}if (root->left == NULL && root->right == NULL){return 1;}return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

3、二叉树第k层节点个数

需要保证k大于0才可,当根节点为空,则返回0,当k等于1时只有一层一个节点,返回1,k>1时第k层节点数就相当于它左右孩子的第k-1层节点数相加。

int BinaryTreeLevelKSize(BTNode* root, int k)
{assert(k > 0);if (root == NULL){return 0;}if (k == 1){return 1;}return BinaryTreeLevelKSize(root->left, k - 1)+ BinaryTreeLevelKSize(root->right, k - 1);
}

4、二叉树查找值为x的节点

跟节点为空则找不到返回NULL,当根节点的值为要找的值时返回该节点,不相等则分别判断它的左右孩子节点,直到找到为止。

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL){return NULL;}if (root->data == x){return root;}BTNode* ret = BinaryTreeFind(root->left,x);if (ret){return ret;}return BinaryTreeFind(root->right, x);
}

三、二叉树创建及销毁

1、通过前序遍历数组创建二叉树

读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

#include <stdio.h>
#include<stdlib.h>
typedef char BTDataType;typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
} BTNode;
BTNode* BinaryTreeCreate(BTDataType* a, int* pi) {if (a[*pi] == '#') {++*pi;return NULL;}BTNode* root = (BTNode*)malloc(sizeof(BTDataType));root->data = a[*pi];++*pi;root->left = BinaryTreeCreate(a, pi);root->right = BinaryTreeCreate(a, pi);return root;
}
//中序遍历
void InOrder(BTNode* root)
{if(root==NULL){return;}InOrder(root->left);printf("%c ",root->data);InOrder(root->right);
}
int main() {char a[100];scanf("%s",a);int pi=0;BTNode* root=BinaryTreeCreate(a, &pi);InOrder(root);return 0;
}

2、二叉树的销毁

void BinaryTreeDestory(BTNode* root)
{if (root == NULL){return;}BinaryTreeDestory(root->left);BinaryTreeDestory(root->right);free(root);
}

3、判断是否为完全二叉树

在二叉树层序遍历的基础上修改一下,让空节点也进入队列,遍历时遇到空节点则退出,继续遍历如果结束前还有非空节点则不是完全二叉树。

int BinaryTreeComplete(BTNode* root)
{//创建队列Que q;QueueInit(&q);//如果根节点不为空,则放进队列if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);if (front == NULL){break;}QueuePush(&q, front->left);QueuePush(&q, front->right);QueuePop(&q);}//此时已经遇到空节点,如果再遇到非空节点则不是完全二叉树while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);if (front){QueueDestroy(&q);return false;}QueuePop(&q);}QueueDestroy(&q);return true;
}

四、测试代码

手动构建一个如下图的二叉树,对代码进行测试:
在这里插入图片描述
测试结果应该为:

前序:123874569
中序:832715469
后序:837259641

是否为完全二叉树:0
节点数:9
叶子节点数:4

BTNode* BuyNode(BTDataType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");exit(-1);}node->data = x;node->left = NULL;node->right = NULL;return node;
}int main()
{// 手动构建BTNode* node1 = BuyNode('1');BTNode* node2 = BuyNode('2');BTNode* node3 = BuyNode('3');BTNode* node4 = BuyNode('4');BTNode* node5 = BuyNode('5');BTNode* node6 = BuyNode('6');BTNode* node7 = BuyNode('7');BTNode* node8 = BuyNode('8');BTNode* node9 = BuyNode('9');node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;node2->right = node7;node3->left = node8;node6->right = node9;printf("前序遍历:");BinaryTreePrevOrder(node1);printf("\n");printf("中序遍历:");BinaryTreeInOrder(node1);printf("\n");printf("后序遍历:");BinaryTreePostOrder(node1);printf("\n");printf("层序遍历:");LevelOrder(node1);printf("\n");printf("BinaryTreeComplete:%d\n", BinaryTreeComplete(node1));printf("BinaryTreeSize:%d\n", BinaryTreeSize(node1));printf("BinaryTreeLeafSize:%d\n", BinaryTreeLeafSize(node1));BinaryTreeDestory(node1);node1 = NULL;return 0;
}

运行结果:

在这里插入图片描述
运行结果与预测结果一致。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

17.适配器模式(Adapter)

意图&#xff1a;将一个类的接口转换为Client希望的另一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的那些类在一起工作。 UML图 Target&#xff1a;定义Client使用的与特定领域相关的接口。 Client&#xff1a;与符合Target接口的对象协同工作。 Adaptee&#xf…

vue+element plus 使用table组件,清空用户的选择项

<el-table ref"tableRef"> .... </el-table> <script lang"ts" setup> import { onMounted, reactive, ref, nextTick } from vue const clearBtn () > {console.log(清空用户的选择项)tableRef.value.clearSelection() } </scr…

CGI与FastCGI的区别在哪里,FastCGI的应用场景讲解

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

qml Combobox用法介绍与代码演示

ComboBox 是 QML 中的一个组件,用于在下拉列表中显示一组项供用户选择。它是 Qt Quick Controls 2 模块中的一个组件,经常用于创建用户界面。 下面是 ComboBox 的一些基本用法: 1. 基本使用: import QtQuick 2.15 import QtQuick.Controls 2.15ApplicationWindow {visib…

在服务器上创建git仓库

1、在服务器上创建git仓库 选择一个创建文件夹的地方&#xff0c;这个地方不会将源码存放在这里&#xff0c;只用于版本控制 # 创建一个专门放置git的文件夹&#xff0c;也可以叫其它名 mkdir git && cd git # 创建自己项目的文件夹&#xff0c;文件夹后面要带 .git…

PBR纹理的10种贴图

PBR 是基于物理的渲染的首字母缩写。它试图通过模拟材料如何吸收和反射光&#xff0c;以模仿现实世界中的光流的方式产生视觉效果。最近的游戏引擎由于其逼真的效果而越来越多地使用 PBR 纹理。对于实时渲染&#xff0c;它们被认为是真实世界场景的最佳近似值。 推荐&#xff…

iOS 17 Simulator Failed with HTTP status 400:bad request

升级 xcode 15 要 ios17 的 sdk 才能运行&#xff0c;但是更新这个 sdk 400 错误了 解决方案&#xff1a; 直接去官网下载开发者后台下载dmg文件&#xff0c;使用命令行快速安装即可 https://developer.apple.com/documentation/xcode/installing-additional-simulator-runti…

c++模板初阶

文章目录 前言一、泛型编程1、泛型编程2、函数模板2.1 函数模板的使用2.2 函数模板的实例化2.3 模板参数的匹配原则 3、类模板 前言 一、泛型编程 1、泛型编程 在学习了前面的c重载之后&#xff0c;我们写一个Swap函数用来交换不同类型的数据时&#xff0c;可以使用函数重载&…

Learn Prompt-Prompt 高级技巧:AutoGPT

AutoGPT 是一个由Toran Richards创建的流行开源项目。它利用GPT4作为大脑&#xff0c;结合langchain的链接思想&#xff0c;连接各种工具和互联网资源&#xff0c;来完成人类给予的任务。您只需要设定一个目标&#xff0c;AutoGPT就会自主规划并逐步执行任务。如果遇到问题&…

xyhcms getshell

下载xyhcms3.6.2021版本并用phpstudy搭建 function get_cookie($name, $key ) {if (!isset($_COOKIE[$name])) {return null;}$key empty($key) ? C(CFG_COOKIE_ENCODE) : $key;$value $_COOKIE[$name];$key md5($key);$sc new \Common\Lib\SysCrypt($key);$value $sc-…

Zabbix5.0_介绍_组成架构_以及和prometheus的对比_大数据环境下的监控_网络_软件_设备监控_Zabbix工作笔记

z 这里Zabbix可以实现采集 存储 展示 报警 但是 zabbix自带的,展示 和报警 没那么好看,我们可以用 grafana进行展示,然后我们用一个叫睿象云的来做告警展示, 会更丰富一点. 可以看到 看一下zabbix的介绍. 对zabbix的介绍,这个zabbix比较适合对服务器进行监控 这个是zabbix的…

PyTorch框架中torch、torchvision、torchaudio与python之间的版本对应关系(9月最新版)

随着python语言和pytorch框架的更新&#xff0c;torch\torchvision\torchaudio与python之间的版本对应关系也在不断地更新。 最新版本torch与torchvision对应关系如下&#xff1a; 稍旧版本torch与torchvision对应关系如下&#xff1a; 最新版本torch与torchaudio对应关系如下…

计算机竞赛 深度学习 机器视觉 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) …

如何将视频进行分割?这几种分割方法了解一下

当我们将视频分成几段后&#xff0c;可以更好地组织和管理不同的片段&#xff0c;方便后续查找和使用。我们可以根据需要调整视频的长度和内容&#xff0c;满足不同的观看需求。此外&#xff0c;分段视频可以更好地适应不同的观看场景&#xff0c;可以更方便地分享和传播&#…

【网络协议】Http-上

Http请求结构&#xff1a; 结构图1&#xff1a; 实验解析请求报文&#xff1a; 1.在Edge浏览器上输入ip地址端口号文件资源&#xff0c;也就是下图中的120.XX.139.29:8888/A/B/c.html 2.我的程序接收到了一个没有有效载荷的http请求(呼应上面的结构图1)&#xff0c;如下 GET …

三维模型3DTile格式轻量化在数据存储的重要性分析

三维模型3DTile格式轻量化在数据存储的重要性分析 三维模型3DTile格式轻量化在数据存储中占有重要地位。随着科技的不断发展&#xff0c;尤其是空间信息科技的进步&#xff0c;人们对于三维地理空间数据的需求日益增长。然而&#xff0c;这类数据通常具有大尺度、高精度等特点&…

pip pip3安装库时都指向python2的库

当在python3的环境下使用pip3安装库时&#xff0c;发现居然都指向了python2的库 pip -V pip3 -V安装命令更改为&#xff1a; python3 -m pip install <package>

C++跳坑记:位移超出范围的处理

在C编程中&#xff0c;数据类型的选择不仅影响内存占用和性能&#xff0c;还可以对某些操作的结果产生意想不到的影响。今天&#xff0c;我将分享一个关于C在不同变量类型下位移操作结果的发现。 位移操作是C中常见的对整数的高效操作之一。然而&#xff0c;我们可能会忽视一个…

交换机端口镜像详解

交换机端口镜像是一种网络监控技术&#xff0c;它允许将一个或多个交换机端口的网络流量复制并重定向到另一个端口上&#xff0c;以便进行流量监测、分析和记录。通过端口镜像&#xff0c;管理员可以实时查看特定端口上的流量&#xff0c;以进行网络故障排查、安全审计和性能优…

docker总结

Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…