完整教程:嵌入式数据结构笔记七——二叉树

news/2025/9/24 12:19:45/文章来源:https://www.cnblogs.com/wzzkaifa/p/19108943

文章目录

  • 前言
  • 一、概念:
  • 二、树形结构:
  • 三、二叉树:
  • 四、完全二叉树的操作:
    • 1.节点定义
    • 2.创建完全二叉树
    • 3. 二叉树深度优先遍历(递归实现)
    • 4. 二叉树广度优先遍历
    • 5. 创建非完全二叉树
    • 6. 获得树的高度
    • 7. 二叉树深度优先遍历(非递归实现)
  • 重点


前言

Linux系统是一种什么结构?队列可以在什么场景下用?


正文内容:

一、概念:

二、树形结构:

在这里插入图片描述

  • 节点:组成树形结构的一个小的单元称为节点
    • 根节点:只有后继,没有前驱
    • 分支节点:既有前驱,又有后继
    • 叶子节点:只有前驱,没有后继
  • 前驱(祖先):由哪个节点可以访问到该节点
  • 后继(子孙):该节点可以后续访问到哪些节点
  • 度:后继节点的个数
  • 层:根节点层数为1,后续每引申出的一个节点就在该节点层数上+1
  • 树的层树:树的层数由层数最高的节点对应的层数表示树的层数
  • 高度:节点高度是由该节点到最远的叶子节点的距离表示该节点高度
  • 深度:节点深度是由该节点到根节点的距离表示节点深度

三、二叉树:

  • 树形结构中的所有节点度数最大为2,称为二叉树
  • 二叉树节点类型:
    • 叶子节点
    • 只有左孩子
    • 只有右孩子
    • 左右孩子都有

在这里插入图片描述

  • 满二叉树——所有叶子节点均在同一层,且每层节点个数均为最大值。
    • 满二叉树第k层节点有2k−12^{k-1}2k1
    • 满二叉树前k层节点有2k−12^k-12k1

在这里插入图片描述

  • 完全二叉树——二叉树的编号(如果节点编号为n,左孩子编号:2n,右孩子编号为:2n+1)展开后是连续的,称为完全二叉树。

在这里插入图片描述

  • 完全二叉树的遍历形式:
    • 深度优先遍历(DFS)
      • 前序遍历(先序遍历):根左右
      • 中序遍历:左根右
      • 后序遍历:左右根
        • 已知中序后序遍历求先序——画图
    • 广度优先遍历(BFS)
      • 层序遍历:逐层从左到右依次遍历
        • 下图层序遍历的顺序为ABCDEFGH在这里插入图片描述

四、完全二叉树的操作:

1.节点定义

在这里插入图片描述

/* 二叉树节点类型 */
typedef struct node {
int no;
//编号
struct node *pleftchild;
//左子树根节点地址
struct node *prightchild;
//右子树根节点地址
}treenode;

2.创建完全二叉树

  • 通过函数递归完成完全二叉树的创建
    • 申请节点空间
    • 存放数据编号
    • 如果存在左子树递归创建左子树
    • 如果存在右子树递归创建右子树
      在这里插入图片描述

代码如下:

/* 完全二叉树的创建 */
treenode *create_complete_btree(int startno, int endno)
{
treenode *ptmpnode = NULL;
ptmpnode = malloc(sizeof(treenode));
if(NULL == ptmpnode)
{
perror("fail to malloc");
return NULL;
}
ptmpnode->no = startno;
ptmpnode->pleftchild = ptmpnode->prightchild = NULL;
if (2*startno <= endno)
{
ptmpnode->pleftchild = create_complete_btree(2*startno, endno);
}
if (2*startno + 1 <= endno)
{
ptmpnode->prightchild = create_complete_btree(2*startno+1,endno);
}
return ptmpnode;
}

3. 二叉树深度优先遍历(递归实现)

  • 前序遍历:
/* 前序遍历 */
int preorder_btree(treenode *proot)
{
printf("%d ", proot->no);
if (proot->pleftchild != NULL)
{
preorder_btree(proot->pleftchild);
}
if (proot->prightchild != NULL)
{
preorder_btree(proot->prightchild);
}
return 0;
}
  • 中序遍历:
/* 中序遍历 */
int inorder_btree(treenode *proot)
{
if (proot->pleftchild != NULL)
{
inorder_btree(proot->pleftchild);
}
printf("%d ", proot->no);
if (proot->prightchild != NULL)
{
inorder_btree(proot->prightchild);
}
return 0;
}
  • 后序遍历:
/* 后序遍历 */
int postorder_btree(treenode *proot)
{
if (proot->pleftchild != NULL)
{
postorder_btree(proot->pleftchild);
}
if (proot->prightchild != NULL)
{
postorder_btree(proot->prightchild);
}
printf("%d ", proot->no);
return 0;
}
  • 二叉树的销毁:
/* 销毁完全二叉树 */
int destroy_btree(treenode *proot)
{
if (proot->pleftchild)
{
destroy_btree(proot->pleftchild);
}
if (proot->prightchild)
{
destroy_btree(proot->prightchild);
}
free(proot);
return 0;
}

4. 二叉树广度优先遍历

  • 层序遍历:
    在这里插入图片描述

代码如下:

/* 层序遍历 */
int layoutorder_btree(treenode* proot)
{
linkqueue *ptmpqueue = create_empty_linkqueue();
treenode *ptmpnode = NULL;
//队列中存放的数据类型是 treenode* 型
enter_linkqueue(ptmpqueue, proot);
while(!is_empty_linkqueue(ptmpqueue))
{
ptmpnode = exit_linkqueue(ptmpqueue);
printf("%d ",ptmpnode->no);
if(ptmpnode->pleftchild != NULL)
{
enter_linkqueue(ptmpqueue, ptmpnode->pleftchild);
}
if(ptmpnode->prightchild != NULL)
{
enter_linkqueue(ptmpqueue, ptmpnode->prightchild);
}
}
destory_linkqueue(&ptmpqueue);
return 0;
}

5. 创建非完全二叉树

  • 非完全二叉树,每个结构不一定相同,所以需要从终端接收用户输入决定二叉树的创建
    在这里插入图片描述

代码如下:

/* 创建非完全二叉树 */
treenode *create_btree(void)
{
char ch = 0;
treenode *ptmpnode = NULL;
scanf(" %c", &ch);
if ('#' == ch)
{
return NULL;
}
ptmpnode = malloc(sizeof(treenode));
if (NULL == ptmpnode)
{
perror("fail to malloc");
return NULL;
}
//在节点定义中加入成员:char data;
ptmpnode->data = ch;
ptmpnode->pleftchild = create_btree();
ptmpnode->prightchild = create_btree();
return ptmpnode;
}

6. 获得树的高度

/* 获得树的高度 */
int get_bintree_height(treenode *proot)
{
int leftheight = 0;
int rightheight = 0;
if (NULL == proot)// 递归终止条件
{
return 0;
}
leftheight = get_bintree_height(proot->pleftchild);
// 递归计算左子树的高度 
rightheight = get_bintree_height(proot->prightchild);
// 递归计算右子树的高度 
// 返回左右子树中较大的高度 + 1
return (leftheight > rightheight ? leftheight : rightheight) + 1;
}

在这里插入图片描述

  • 递归调用树形图:
    在这里插入图片描述

7. 二叉树深度优先遍历(非递归实现)

在这里插入图片描述

  • 前序遍历:
/* 非递归前序遍历 */
int preorder_btree_bystack(treenode *proot)
{
linkstack *ptmpstack = NULL;
treenode *ptmpnode = NULL;
ptmpstack = create_empty_linkstack();
ptmpnode = proot;
while (1)
{
while (ptmpnode != NULL)
{
printf("%c ", ptmpnode->data);
push_linkstack(ptmpstack, ptmpnode);
ptmpnode = ptmpnode->pleftchild;
}
if (is_empty_linkstack(ptmpstack))
{
break;
}
ptmpnode = pop_linkstack(ptmpstack);
//回溯
ptmpnode = ptmpnode->prightchild;
}
return 0;
}
  • 中序遍历:
/* 非递归中序遍历 */
int inorder_btree_bystack(treenode *proot)
{
linkstack *ptmpstack = NULL;
treenode *ptmpnode = NULL;
ptmpstack = create_empty_linkstack();
ptmpnode = proot;
while (1)
{
while (ptmpnode != NULL)
{
push_linkstack(ptmpstack, ptmpnode);
ptmpnode = ptmpnode->pleftchild;
}
if (is_empty_linkstack(ptmpstack))
{
break;
}
ptmpnode = pop_linkstack(ptmpstack);
//回溯
printf("%c ", ptmpnode->data);
ptmpnode = ptmpnode->prightchild;
}
return 0;
}
  • 后序遍历:
    • 因为最后打印根节点,所以根节点需要2次入栈
    • 第一次入栈,是为了出栈时找到该节点的右孩子,找到右孩子后,继续将节点入栈
    • 第二次入栈,是为了打印该节点
/* 非递归后序遍历 */
int postorder_btree_bystack(treenode *proot)
{
linkstack *ptmpstack = NULL;
treenode *ptmpnode = NULL;
ptmpstack = create_empty_linkstack();
ptmpnode = proot;
while (1)
{
while (ptmpnode != NULL)
{
ptmpnode->flag = 1;
//在节点定义中加入成员:int flag;
push_linkstack(ptmpstack, ptmpnode);
ptmpnode = ptmpnode->pleftchild;
}
if (is_empty_linkstack(ptmpstack))
{
break;
}
ptmpnode = pop_linkstack(ptmpstack);
if (1 == ptmpnode->flag)
{
ptmpnode->flag = 0;
push_linkstack(ptmpstack, ptmpnode);
ptmpnode = ptmpnode->prightchild;
}
else if (0 == ptmpnode->flag)
{
printf("%c ", ptmpnode->data);
ptmpnode = NULL;
//正确回溯到上一个节点
}
}
return 0;
}

重点

  • 深度优先遍历(DFS)
  • 广度优先遍历(BFS)

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

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

相关文章

51单片机-驱动DS1302时钟芯片模块教程 - 实践

51单片机-驱动DS1302时钟芯片模块教程 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

JVM 类加载器详解 - 实践

JVM 类加载器详解 - 实践2025-09-24 12:16 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; fo…

石碣做网站优化偷wordpress模板

wildfly管理控制台红帽JBoss企业应用程序平台&#xff08;EAP&#xff09;和WildFly具有共生关系 。 简而言之&#xff0c;红帽JBoss企业应用程序平台&#xff08;JBoss EAP&#xff09;保留了WildFly社区项目&#xff08;以前称为JBoss Application Server&#xff09;的所有创…

音乐网站制作教程步骤wordpress登陆后查看

李宗盛有首歌的歌词里写到&#xff1a;「工作是容易的&#xff0c;赚钱是困难的」。乍一听感觉有点矛盾&#xff0c;工作的一个重要结果不就是赚钱么&#xff0c;为什么工作容易赚钱却难&#xff1f;但仔细一想就恍然其中想表达的意思了。 工作的本质是出售劳动价值&#xff0c…

网站域名备案需要什么罗湖营销型网站建设

RPC和 HTTP是两种常见的通信方式&#xff0c;它们在设计目标、使用场景和技术实现上有显著区别。以下是它们的详细对比&#xff1a; 1. 定义与核心思想 特性RPCHTTPRemote Procedure Call远程过程调用HyperText Transfer Protocol超文本传输协议定义一种协议或框架&#xff0…

昌平哪有做网站的公司比较大网站建设公司

&#x1f6eb;更多ssm知识见SSM_面向CRUD编程专栏 &#x1f695;本博客总结自黑马程序员的ssm框架视频 &#x1f692;博主对于该知识尚在学习阶段 &#x1f684;如果发现存在问题请毫不吝啬的指出 &#x1f680;&#x1f680;扎哇太枣糕的博客主页&#x1f680;&#x1f680; 目…

网站建设推广安徽国内专业网站设计

删除的场景&#xff1a; 解决思路&#xff1a; 1、计算操作后的总页数 2、删除成功之后的总页数与当前总页数进行比较 3、如果删除成功之后的总页数比小于当前总页数&#xff0c;需要把当前页码减去1&#xff1b;否则&#xff0c;直接进行列表数据的请求 代码实现 /*总条数…

中国做网站的公司新手网页制作

2022-01-25 更新&#xff1a;博客新地址&#xff1a;https://www.itbob.cn/&#xff0c;文章距上次编辑时间较远&#xff0c;部分内容可能已经过时&#xff01; 文章目录● 前言● 注册 Cloudflare● 添加站点● 修改DNS● 开启 HTTPS● 重定向强制 HTTPSHTTP&#xff08;超文本…

Unity小游戏接入抖音敏感词检测 - 指南

Unity小游戏接入抖音敏感词检测 - 指南2025-09-24 12:04 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !…

SQLite的并发问题

转载自:C# 下 SQLite 并发操作与锁库问题的 5 种解决方案_51CTO博客_sqlcipher c# SQLite是轻量级的数据库,可用于嵌入式设备,仅需几百KB的内存即可工作,整个数据库存储在单一文件中,便于管理,迁移,备份。无需繁…

域渗透靶场-vulntarget-a综合靶场

nmap发现开放80端口浏览器访问,是通达oa可以搜索poc或者使用oa利用工具拿到shell 通过账号admin 密码滞空,进入后台我们这里使用通达OA 11.2 后台getshell 点击系统管理 -> 系统参数设置 -> OA服务设置 找到We…

在线设计logo的网站小程序开发和app开发差别

1、读取哈使用方法不同SAP内存使用SET/GET parameters方法&#xff1b;ABAP内存使用 EXPORT 和 IMPORT 方法&#xff1b;2、共享范围不同SAP内存可以被所有的主session访问&#xff0c;内存数据可以同一个session中不同程序之间&#xff0c;或者不同session之间&#xff1b;AB…

现在的网站开发用什么技术南宁百度seo

简介&#xff1a; MaxCompute 是面向分析的企业级 SaaS 模式云数据仓库&#xff0c;以 Serverless 架构提供快速、全托管的在线数据仓库服务&#xff0c;消除了传统数据平台在资源扩展性和弹性方面的限制&#xff0c;最小化用户运维投入&#xff0c;使您可以经济并高效的分析处…

温州网站 公司做网站招标

一、源码特点 idea 开发 SSM 学员信息管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…

网站建设主要学什么软件济宁哪里有网站建设

五层&#xff1a; 应用层&#xff1a;应用层是最高层&#xff0c;负责为用户提供网络服务和应用程序。在应用层&#xff0c;用户应用程序与网络进行交互&#xff0c;发送和接收数据。典型的应用层协议包括HTTP&#xff08;用于网页浏览&#xff09;、SMTP&#xff08;用于电子邮…

数组和链表读取、插入、删除以及查找的区别

数组和链表是两种常见的数据结构,它们在读取、插入、删除操作上有显著差异,下面详细说明: 1. 读取(访问)操作数组: 数组是连续的内存空间,元素按索引(下标)存储,因此可以通过索引直接访问任意位置的元素,时…

day 09 课程

day 09 课程课程:https://www.bilibili.com/video/BV1o4411M71o/?spm_id_from=333.788.videopod.episodes&p=168 9.1 了解函数———————————————————————————————————————…

在K8S中,日志分析工具有哪些可以与K8S集群通讯?

在Kubernetes中,日志分析工具与集群的通信方式多样,可以根据部署位置和采集方式分为几大类。以下是主流工具的详细分类和介绍: 📊 日志分析工具分类概览 graph TDA[K8S日志分析工具] --> B1[集群内部部署]A --…

在K8S中,网络通信模式有哪些?

好的,这是一个非常核心的问题。Kubernetes 的网络模型是一个复杂的体系,但我们可以将其分解为几个清晰的层次来理解。 Kubernetes 网络通信模式可以分为四大类,下图清晰地展示了这四类通信的全景:A[Kubernetes 网络…

中山网站代运营python nginx做网站

Creator 版本&#xff1a; 3.8.2 目标平台&#xff1a;小游戏开发 压缩后 我不知道别人压缩几百kb是怎么做到的。不过哪个要钱。 我这个技巧不用花钱。 论坛有教程但是没有教详细怎么做。 开整&#xff01; 做一个空白的场景。然后写一个load脚本。load主场景。 从代码可…