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

目录

一 二叉树的遍历

1 构建一个二叉树

2 前序遍历

3 中序遍历

4 后续遍历

5 层序 

6 二叉树销毁

二 应用(递归思想)

1 二叉树节点个数

2 叶子节点个数

3 第K层的节点个数

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

5 判断是否是二叉树


一 二叉树的遍历

学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉 树中的节点进行相应的操作,并且每个节点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历 是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础

二叉树是: 1. 空树  2. 非空:根节点,根节点的左子树、根节点的右子树组成的。

前序、中序以及后序遍历: 

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

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

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

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

由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为 根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

代码实现:

1 构建一个二叉树

typedef struct BinaryTreeNode
{struct BinaryTreeNode* left;struct BinaryTreeNode* right;int val;
}BTNode;BTNode* BuyNode(int x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");exit(-1);}node->left = NULL;node->right = NULL;node->val = x;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);node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;PrevOrder(node1);printf("\n");InOrder(node1);printf("\n");PostOrder(node1);printf("\n");return 0;
}

 2 前序遍历

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

3 中序遍历

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

 4 后续遍历

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

5 层序 

void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Que* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->next = NULL;newnode->val = x;if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;}bool QueueEmpty(Que* pq)
{assert(pq);return pq->head == NULL;
}void QueuePop(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}QDataType QueueFront(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->val;
}void LevelOrder(BTNode* root)
{Que q;QueueInit(&q);if (root){QueuePush(&q, root);}while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);printf("%d ", front->val);if (front->left){QueuePush(&q, front->left);}if (front->right){QueuePush(&q, front->right);}QueuePop(&q);}
}

6 二叉树销毁

//二叉树的销毁
void TreeDestroy(BTNode* root)
{if (root == NULL){return;}TreeDestroy(root->left);TreeDestroy(root->right);free(root);}

二 应用(递归思想)

1 二叉树节点个数

int size = 0;
int TreeSize(BTNode* root)
{if (root == NULL){return 0;}else{size++;}TreeSize(root->left);TreeSize(root->right);return size;}

我们还可以改进

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

 2 叶子节点个数

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);
}

3 第K层的节点个数

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

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

BTNode* TreeFind(BTNode* root, int x)
{if (root == NULL){return NULL;}if (root->val == x){return root;}BTNode* ret = NULL;//从左树找 找到了就返回 不找右树了ret = TreeFind(root->left, x);if (ret){return ret;}//左树没找到 就开始找右树ret = TreeFind(root->right, x);if (ret){return ret;}}

5 判断是否是二叉树

void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Que* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->next = NULL;newnode->val = x;if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;}bool QueueEmpty(Que* pq)
{assert(pq);return pq->head == NULL;
}void QueuePop(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}QDataType QueueFront(Que* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->val;
}int TreeComplete(BTNode* root)
{Que q;QueInit(&q);if (root != NULL){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);QueuePop(&q);if (front != NULL){QueueDestroy(&q);return false;}}QueueDestroy(&q);return true;
}

二叉树的链式结构的本质思想是递归, 对于递归不了解的小伙伴可以看看我之前的博客, 也可以自己尝试画一下递归展开图,下一节讲OJ题目.实战才最有效!继续加油! 

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

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

相关文章

HQChart支持的画图工具列表

HQChart支持的画图工具列表 线段类线段射线标价线垂直线箭头趋势线水平线水平线段平行射线平行线平行通道价格通道线M头W底头肩型波浪尺AB波浪尺箱型线涂鸦线段 图形类圆弧线矩形平行四边形三角形圆对称角度 文字类文本箭头NoteAnchoredTextPriceLabelPriceNote 其他江恩角度线…

Linux:redis集群(3.*版本 和 5.*版本)搭建方法

介绍 至少6个实例才能组成集群。3主3从会自动分配 Redis集群原理 Redis集群架构 Redis Cluster采用虚拟槽分区,将所有的数据根据算法映射到0~16383整数槽内 Redis Cluster是一个无中心的结构 每个节点都保存数据和整个集群的状态 集群角色 Master:Master…

YOLOv7改进策略:RIFormerBlock助力检测|CVPR2023 RIFormer:无需TokenMixer也能达成SOTA性能的极简ViT架构

💡💡💡本文属于原创独家改进: 稀疏重参数RIFormerBlock模型引入YOLOv7进行创新性 RIFormerBlock | 亲测在多个数据集实现涨点; 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨✨✨前沿最新计算机顶会复现 🚀🚀🚀YOLOv7自研创新结合,轻松…

Arduino安装esp32-cam以及CameraWebServer实例的实现

目录 1. 硬件2. 软件2.1 arduino下载安装2.2 arduino配置esp32-cam开发板文件2.3 下载相应版本的esp32 3. ESP32-CAM实例:CameraWebServer3.1 选择开发板3.2 选择示例代码进行验证3.3 烧录进行实测 1. 硬件 没买下载主板的可使用usb转串口模块进行烧录,接…

小程序:下拉刷新+上拉加载+自定义导航栏

下拉刷新 &#xff1a; <scroll-view scroll-y"true" 允许纵向滚动 refresher-enabled"true" 开启自定义下拉刷新 默认为false :refresher-triggered&quo…

iOS 获取模拟器沙盒路径

xcrun simctl get_app_container booted Bundle Identifier data

WorkPlus定制化的局域网会议软件,提供安全稳定的会议体验

在现代商业环境中&#xff0c;迅速而高效的沟通是企业成功的关键要素之一。而在传统的会议模式下&#xff0c;时间成本和地理限制往往给企业带来不小的困扰。针对这一问题&#xff0c;WorkPlus推出了一款创新的局域网会议软件——WorkPlus Meet&#xff0c;旨在为企业创造高效的…

数据集笔记:分析OpenCellID 不同radio/ create_time update_time可视化

1 读取数据 &#xff08;以新加坡的cellID为例&#xff09; import geopandas as gpd import pandas as pdopencellidpd.read_csv(OpenCellID_SG.csv,headerNone,names[radio,mcc,net,area,cell,unit,lon,lat,range,samples,changeable1,created1,updated,AveSignal]) opence…

【数据库问题】删除数据库失败,提示:there is 1 other session using the database

删除数据库失败&#xff0c;提示&#xff1a;there is 1 other session using the database 解决办法&#xff1a; SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE datnametest_database AND pid<>pg_backend_pid(); 使用上述命令先关…

wireshark抓rtp包,提取出H265裸流数

调试rtsp收发流时&#xff0c;经常会需要抓包以确认是网络问题还是程序问题还是其它问题。通过tcpdump或者wireshark抓到的包通常是rtp流&#xff0c;保存为.pcap格式文件后中&#xff0c;可通过wireshark进行解析&#xff0c;得出h264裸流&#xff0c;并保存为文件。 1.wires…

淘宝天猫商品评论数据接口,淘宝天猫商品评论API接口,淘宝API

淘宝商品评论数据接口可以通过淘宝开放平台API获取。 通过构建合理的请求URL&#xff0c;可以向淘宝服务器发起HTTP请求&#xff0c;获取商品评论数据。接口返回的数据一般为JSON格式&#xff0c;包含了商品的各种评价信息。获取到商品评论数据后&#xff0c;可以对其进行处理…

stm32 hal库 st7789 1.54寸lcd

文章目录 前言一、软件spi1.cubemx配置2.源码文件 二、硬件spi1.cubemx配置2.源码文件3.小小修改 总结 前言 1.54寸lcd 240*240 一、软件spi 1.cubemx配置 一定要注意把这几个东西上拉。 使用c8 2.源码文件 我使用的是中景园的源码&#xff0c;他本来是是标准库的稍微修改…

docker入门加实战—docker常见命令

docker入门加实战—docker常见命令 在介绍命令之前&#xff0c;先用一副图形象的展示一下docker的命令&#xff1a; 常见命令 docker的常见命令和文档地址如下表&#xff1a; 命令说明文档地址docker pull拉取镜像docker pulldocker push推送镜像到DockerRegistrydocker pus…

模拟pdf运行js脚本触发xss攻击及防攻击

一、引入pdfbox依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>3.0.0</version> </dependency> 二、生成一个带js脚本的pdf文件 //Creating PDF document object PDDocum…

JMeter接口测试:简单到离谱(只需Python和几行代码)

JMeter是一款开源的负载测试工具&#xff0c;可以进行各种类型的性能和功能测试&#xff0c;其中包括接口测试。本文将介绍如何使用Python语言利用JMeter进行接口测试&#xff0c;并提供一些实用的技巧和最佳实践。 同时&#xff0c;我也准备了一份软件测试视频教程&#xff0…

【【萌新的SOC学习之GPIO之MIO控制LED实验程序设计】】

萌新的SOC学习之GPIO之MIO控制LED实验程序设计 如何设置完GPIO并且传递数据 我们先了解GPIO引脚的配置 每一个GPIO引脚都可以设置成输入输出 &#xff0c;只有GPIO8 7 只能作为输出 我们现在做一个例子 GPIO 的bank我们知道有4个 bank0 1 2 3 DIRM_0 就是第一个bank 需要写入…

访问Apache Tomcat的manager页面

配置访问Tomcat manager页面的用户名、密码、角色 Tomcat安装完成后&#xff0c;包含了一个管理应用&#xff0c;默认安装在 <Tomcat安装目录>/webapps/manager 例如&#xff1a; 要使用管理页面的功能&#xff0c;需要在conf/tomcat-users.xml文件中配置用户、密码及…

我用了多年的前端框架,强烈推荐!

大家好&#xff0c;我是鱼皮&#xff0c;今天给大家分享一个我自己用了多年、现在团队也在用的前端框架 —— Ant Design Pro。 什么是 Ant Design Pro&#xff1f; Ant Design Pro 是由蚂蚁金服开发的、基于 Ant Design 组件库的开发框架&#xff0c;专门用于构建企业级管理…

LeetCode【15】三数之和

题目&#xff1a; 解析&#xff1a; 参考&#xff1a;https://zhuanlan.zhihu.com/p/111715985 代码&#xff1a; public static List<List<Integer>> threeSum(int[] nums) {// 先排序Arrays.sort(nums);List<List<Integer>> result new ArrayLis…

python pip安装超时使用国内镜像

网络环境差的时候需要我们独立的进行相对应的包下载离线安装&#xff0c;或者给pip 加上 国内的镜像源比如加上清华的镜像源&#xff1a; 参考网址&#xff1a;pypi | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror https://mirrors.tuna.tsinghua…