数据结构(5)二叉树的存储、创建与四种遍历算法
一、二叉树的基本概念二叉树Binary Tree是每个节点最多拥有两棵子树的树结构通常子树被称作左子树和右子树。1.1 二叉树的递归定义二叉树是 nn≥0个节点的有限集合该集合或者为空集空二叉树或者由一个根节点和两棵互不相交的、分别称为左子树和右子树的二叉树组成。1.2 二叉树的性质第 i 层最多有 2^(i-1) 个节点深度为 k 的二叉树最多有 2^k - 1 个节点叶子节点数 n₀ 度为2的节点数 n₂ 1。1.3 二叉树的存储本文采用链式存储每个节点包含一个数据域和两个指针域分别指向左孩子和右孩子。二、二叉树的节点定义btree.h#ifndef _BTREE_H_ #define _BTREE_H_ typedef int data_t; typedef struct btnode { data_t data; // 数据域 struct btnode *pl; // 指向左子树 struct btnode *pr; // 指向右子树 } btree_t; // 二叉树节点类型 #endif三、由前序和中序序列手动还原二叉树已知一棵二叉树的先序序列为A B D F C E G H中序序列为B F D A G E H C手动还原这棵二叉树。3.1 还原过程基本原理前序遍历根→ 左 → 右第一个元素是根中序遍历左 →根→ 右根的左边是左子树右边是右子树Step 1确定整棵树的根前序序列第一个元素是A所以A 是根。Step 2在中序序列中划分左右子树中序序列B F D A G E H C以A为分界A 的左边B F D→ A 的左子树A 的右边G E H C→ A 的右子树Step 3递归还原左子树B F D左子树节点集合为 {B, F, D}对应前序序列为B D F前序中紧跟 A 之后的 3 个属于左子树的元素。前序中B排第一 →B 是左子树的根在中序B F D中B 左边为空 → B 没有左子树B 右边F D→ B 的右子树继续分析F DB 的右子树对应前序D F前序中D排第一 →D 是根在中序F D中D 左边F→ D 的左子树D 右边为空 → D 没有右子树F是叶子节点Step 4递归还原右子树G E H C右子树节点集合为 {G, E, H, C}对应前序序列为C E G H。前序中C排第一 →C 是右子树的根在中序G E H C中C 左边G E H→ C 的左子树C 右边为空 → C 没有右子树继续分析G E HC 的左子树对应前序E G H前序中E排第一 →E 是根在中序G E H中E 左边G→ E 的左子树E 右边H→ E 的右子树G和H都是叶子节点3.2 还原结果最终得到的二叉树结构如下A / B \ D / F C / E / \ G H也可以画得更完整A / \ B C \ / D E / / \ F G H3.3 后序遍历验证后序遍历左 → 右 → 根F D B G H E C A先遍历左子树F → D → B再遍历右子树G → H → E → C最后根A合并F D B G H E C A✓3.4 后序线索树后序遍历序列F → D → B → G → H → E → C → A在后序遍历序列中每个节点的前驱序列中前一个和后继序列中后一个如下节点前驱pre后继postF无第一个DDFBBDGGBHHGEEHCCEAAC无最后一个后序线索树中利用空指针域存放遍历序列中的前驱/后继信息左指针指前驱右指针指后继其中首节点 F 的前驱线索和末节点 A 的后继线索为空。3.5 将二叉树转换为对应的树或森林转换规则二叉树转树/森林的核心是左孩子右兄弟表示法的逆过程——节点的左孩子转为树中的第一个孩子节点的右兄弟转为树中的下一个兄弟。转换过程1.从根节点 A 开始A 的左孩子 B 变成 A 的第一个孩子A 的右孩子 C 变成 A 的下一个兄弟——但 A 是根无兄弟所以 C 作为 A 的另一个孩子即 B 的右兄弟 → A 的第二个孩子2.但更准确地说A 的左子树和右子树分别构成两棵树形成森林第一棵树根为 AA 的左孩子 B 是 A 的第一个孩子D 是 B 的孩子F 是 D 的孩子第二棵树根为 CE 是 C 的孩子G 和 H 是 E 的孩子森林的树形表示 第一棵树 第二棵树 A C | | B E | / \ D G H | F四、二叉树的创建代码实现扩展先序序列采用扩展先序序列递归创建二叉树。遇到空节点时用#标记。例如序列ABDG##H###CE#I##F##对应的二叉树结构如下A / \ B C / / \ D E F / \ \ G H I核心代码#include stdio.h #include stdlib.h #include btree.h char tree_seq[] ABDG##H###CE#I##F##; int idx 0; // 当前读取位置 btree_t *create_btree(void) { char data tree_seq[idx]; if (data #) { return NULL; // # 表示空节点结束 } btree_t *new malloc(sizeof(btree_t)); if (new NULL) { printf(malloc fail!\n); return NULL; } new-data data; new-pl create_btree(); // 递归创建左子树 new-pr create_btree(); // 递归创建右子树 return new; }思路解析1.从序列中读取一个字符2.如果是#返回NULL表示该子树为空3.否则创建新节点填入数据然后递归创建左子树和右子树4.全局变量idx记录当前读取到序列的第几个字符。五、二叉树的四种遍历方式5.1 前序遍历Pre-Order根 → 左 → 右int pre_order_traverse(btree_t *t) { if (t NULL) return 0; printf(%c , t-data); // 根 pre_order_traverse(t-pl); // 左子树 pre_order_traverse(t-pr); // 右子树 return 0; }输出A B D G H C E I F5.2 中序遍历In-Order左 → 根 → 右int in_order_traverse(btree_t *t) { if (t NULL) return 0; in_order_traverse(t-pl); // 左子树 printf(%c , t-data); // 根 in_order_traverse(t-pr); // 右子树 return 0; }输出G D H B A E I C F5.3 后序遍历Post-Order左 → 右 → 根int post_order_traverse(btree_t *t) { if (t NULL) return 0; post_order_traverse(t-pl); // 左子树 post_order_traverse(t-pr); // 右子树 printf(%c , t-data); // 根 return 0; }输出G H D B I E F C A5.4 三种递归遍历的对比总结遍历方式访问顺序特点前序遍历根 → 左 → 右适合复制/序列化树结构中序遍历左 → 根 → 右对二叉搜索树结果为有序序列后序遍历左 → 右 → 根适合释放内存/计算树的大小递归遍历的共同模式终止条件t NULL时返回递归结构三个函数的代码结构完全相同只是printf语句的位置不同。5.5 层序遍历Level-Order逐层从左到右层序遍历需要借助队列来实现属于广度优先搜索BFS的思想。#include linkqueue.h int layer_order_traverse(btree_t *t) { if (t NULL) return -1; // 步骤1创建队列根节点入队 node_t *pq linkqueue_create(); enqueue(pq, t); // 步骤2循环出队、打印、子节点入队 while (is_empty(pq) ! 1) { btree_t *data NULL; dequeue(pq, data); printf(%c , data-data); if (data-pl ! NULL) enqueue(pq, data-pl); // 左孩子入队 if (data-pr ! NULL) enqueue(pq, data-pr); // 右孩子入队 } // 步骤3销毁队列 linkqueue_destroy(pq); return 0; }输出A B C D E F G H I为什么层序遍历需要队列队列的 FIFO 特性保证了同一层的节点先被访问其子节点后被访问从而实现逐层遍历。六、二叉树的销毁释放二叉树内存需要采用后序遍历的顺序左 → 右 → 根必须先释放子节点再释放父节点否则会丢失子节点的引用野指针。int btree_destroy(btree_t *t) { if (t NULL) return -1; btree_destroy(t-pl); // 递归销毁左子树 btree_destroy(t-pr); // 递归销毁右子树 free(t); // 释放根节点 return 0; }七、主函数与完整运行结果int main(int argc, const char *argv[]) { btree_t *root create_btree(); printf(前序遍历: ); pre_order_traverse(root); putchar(\n); printf(中序遍历: ); in_order_traverse(root); putchar(\n); printf(后序遍历: ); post_order_traverse(root); putchar(\n); printf(层序遍历: ); layer_order_traverse(root); putchar(\n); // btree_destroy(root); // 释放二叉树 return 0; }运行结果text前序遍历: A B D G H C E I F 中序遍历: G D H B A E I C F 后序遍历: G H D B I E F C A 层序遍历: A B C D E F G H I八、总结遍历方式实现方式核心数据结构时间复杂度空间复杂度前序遍历递归系统调用栈O(n)O(h)h为树高中序遍历递归系统调用栈O(n)O(h)后序遍历递归系统调用栈O(n)O(h)层序遍历迭代队列链表实现O(n)O(w)w为最大层宽学习要点回顾1.链式队列的核心入队 尾插出队 头删两者配合保证 FIFO2.二叉树是递归结构遍历算法天然适合递归实现3.前/中/后序遍历的区别仅在于printf的位置4.已知前序 中序序列可以唯一还原二叉树前序定根中序分左右子树5.层序遍历是唯一的非递归遍历需要队列辅助6.销毁二叉树必须使用后序顺序避免野指针7.二叉树可以通过左孩子右兄弟的逆规则转换为树或森林。

相关新闻

显卡健康检测利器:memtest_vulkan显存稳定性测试全攻略

显卡健康检测利器:memtest_vulkan显存稳定性测试全攻略

显卡健康检测利器:memtest_vulkan显存稳定性测试全攻略 【免费下载链接】memtest_vulkan Vulkan compute tool for testing video memory stability 项目地址: https://gitcode.com/gh_mirrors/me/memtest_vulkan 在数字时代,显卡已成为计算机系统…

2026/8/11 4:22:50 阅读更多 →
CPPM报名需要什么资料?在职采购人员准备指南

CPPM报名需要什么资料?在职采购人员准备指南

很多采购人员已经具备多年工作经验,却因为不清楚报名资料、审核流程和时间安排,迟迟没有开始准备。实际上,提前把个人信息和工作经历整理清楚,可以减少报名阶段反复补充材料的情况。一、CPPM报名通常需要哪些资料不同批次的具体要…

2026/8/11 4:22:50 阅读更多 →
5分钟免费iOS激活锁绕过指南:Applera1n解锁iPhone 6s-X完整方案

5分钟免费iOS激活锁绕过指南:Applera1n解锁iPhone 6s-X完整方案

5分钟免费iOS激活锁绕过指南:Applera1n解锁iPhone 6s-X完整方案 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n Applera1n是一款专为iOS 15-16系统设计的免费激活锁绕过工具,专…

2026/8/11 4:21:50 阅读更多 →

最新新闻

UE5 HTTP客户端开发:5分钟实现原生网络通信,告别第三方库配置

UE5 HTTP客户端开发:5分钟实现原生网络通信,告别第三方库配置

1. 项目概述 如果你是一名UE5开发者,想在游戏里加个简单的网络功能,比如从服务器拉取个排行榜数据、验证一下用户登录、或者提交个玩家分数,第一反应是不是头皮发麻?打开搜索引擎,输入“UE5 C HTTP”,扑面而…

2026/8/11 5:12:46 阅读更多 →
VSCode远程开发实战:基于SSH实现高效服务器编程

VSCode远程开发实战:基于SSH实现高效服务器编程

1. 项目概述:为什么我们需要远程开发? 作为一名常年和服务器打交道的开发者,我几乎每天都要面对一个场景:代码在本地跑得好好的,一部署到服务器就各种报错。环境差异、依赖版本、系统配置……这些“水土不服”的问题&a…

2026/8/11 5:12:46 阅读更多 →
基于python的二手房价数据分析大数据可视化房价预测项目3(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于python的二手房价数据分析大数据可视化房价预测项目3(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于python的二手房价数据分析大数据可视化房价预测项目3(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 基于python的二手房价数据分析大数据可视化房价预测项目(含代码,word报告,新数据集…

2026/8/11 5:12:46 阅读更多 →
Dev-C++安装使用全攻略:解决初学者常见问题与配置优化

Dev-C++安装使用全攻略:解决初学者常见问题与配置优化

1. 项目概述:为什么Dev-C依然是初学者的“老朋友”?如果你刚开始学习C或C,尤其是在Windows环境下,那么“Dev-C”这个名字你大概率不会陌生。这个诞生于1998年的集成开发环境(IDE),以其轻量、免费…

2026/8/11 5:12:46 阅读更多 →
VC++2010学习版安装与使用全指南:从下载到调试的完整解决方案

VC++2010学习版安装与使用全指南:从下载到调试的完整解决方案

1. 项目概述:为什么VC2010学习版至今仍是“硬通货”?如果你正在准备计算机二级C语言考试,或者你的大学C语言课程实验环境还停留在十几年前,那么“VC2010学习版”这个名字对你来说一定不陌生。这不仅仅是一个软件,更像是…

2026/8/11 5:12:46 阅读更多 →
Unity 2018模型导入全流程配置指南:从BlendShape到光照贴图

Unity 2018模型导入全流程配置指南:从BlendShape到光照贴图

1. 项目概述:为什么Unity 2018的模型导入值得单独拿出来说?干了这么多年技术美术和项目资源管理,我敢说,超过一半的Unity项目在美术资源导入阶段就埋下了性能、效果和后期维护的“雷”。尤其是当我们谈论Unity 2018这个版本时&…

2026/8/11 5:11:46 阅读更多 →

日新闻

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/v…

2026/8/11 0:00:02 阅读更多 →
前后端分离项目中控制台与接口工具数据差异排查指南

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析:控制台与Apifox的数据差异 最近在调试一个前后端分离项目时,遇到了一个典型问题:后端服务在本地开发环境控制台能正常输出查询数据,但通过Apifox测试时却返回空结果。这种"控制台有数据,接口工具…

2026/8/11 0:00:03 阅读更多 →
AI编程实战:从Claude Code踩坑到游戏开发入门

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友,尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友,都在问我同一个问题:“听说现在用Claude Code这种AI编程工具,小白也能做游戏了,是真的吗&#…

2026/8/11 0:00:03 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/11 1:08:05 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 1:08:05 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/11 1:08:05 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/10 17:07:33 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/11 1:08:06 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/10 17:07:33 阅读更多 →