【C语言数据结构————————二叉树】

文章目录

  • 文章目录

  • 一、什么是树

    • 树的定义

    • 树的种类

    • 树的深度

    • 树的基本术语

  • 二、满二叉树

    • 定义

    • 满二叉树的特点

  • 三、完全二叉树

    • 定义

    • 特点

  • 四、二叉树的性质

  • 五、二叉树的存储结构

    • 顺序存储结构

    • 链式存储结构

  • 六、二叉树的基本操作 

  • 七、二叉树的创建

  • 八、二叉树的遍历

    • 前序遍历

    • 中序遍历

    • 后序遍历

  • 九、二叉树的销毁

  • 十、二叉树中节点的查找

欢迎阅读新一期的c语言数据结构模块————二叉树

✒️个人主页:-_Joker_-

🏷️专栏:C语言数据结构

📜代码仓库:c_code

🌹🌹欢迎大佬们的阅读和三连关注,顺着评论回访🌹🌹


一、什么是树

1.树的定义

树是n(n>=0)个结点的有限集。当n = 0时,称为空树。在任意一棵非空树中应满足:

  1. 有且仅有一个特定的称为根的结点。
  2. 当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1,T2,…,Tm,其中每个集合本身又是一棵树,并且称为根的子树。

2.树的种类

树的种类可以分为以下几种

  • 无序树:树中任意节点的子结点之间没有顺序关系,这种树称为无序树,也称为自由树;
  • 有序树:树中任意节点的子结点之间有顺序关系,这种树称为有序树;
  • 二叉树:每个节点最多含有两个子树的树称为二叉树;
  • 满二叉树:叶节点除外的所有节点均含有两个子树的树被称为满二叉树;
  • 完全二叉树:除最后一层外,所有层都是满节点,且最后一层缺右边连续节点的二叉树称为完全二叉树;
  • 哈夫曼树(最优二叉树):带权路径最短的二叉树称为哈夫曼树或最优二叉树。

3.树的深度

定义一棵树的根结点层次为1,其他结点的层次是其父节点层次加1。一棵树中所有结点的层次的最大值称为这棵树的深度。例如:

如图,图中的树的深度为:3 


4.树的基本术语

  • 结点的度:结点拥有的子树数目
  • 叶子(终端)结点:度为0的结点
  • 分支(非终端)结点:度不为0的结点
  • 树的度:树的各结点度的最大值
  • 内部结点:除根结点之外的分支结点
  • 双亲与孩子结点:结点的子树的根称为该结点的孩子;该结点称为孩子的双亲
  • 兄弟:属于同一双亲的孩子
  • 结点的祖先:从根到该结点所经分支上的所有结点
  • 结点的子孙:该结点为根的子树中的任一结点
  • 结点的层次:表示该结点在树中的相对位置。根为第一层,其他的结点依次下推;若
  • 结点在第L层上,则其孩子在第L+1层上
  • 兄弟节点:双亲在同一层的结点互为兄弟节点
  • 树的深(高)度:树中结点的最大层次
  • 有序树:树中各结点的子树从左至右是有次序的,不能互换。否则,称为无序树
  • 路径长度:从树中某结点Ni出发,能够“自上而下”通过树中结点到达结点Nj,则称Ni到Nj存在
  • 一条路径,路径长度等于这两个结点之间的分支数
  • 树的路径长度:从根到每个结点的路径长度之和。
  • 森林:是m(m≥0)棵互不相交的树的集合

由于二叉树的使用在数据结构中更加广泛,所以我们以二叉树为主来进行讲解,下面介绍一下关于二叉树的基本知识。


二、满二叉树

定义:

二叉树中,如果所有分支结点都存在左子树和右子树并且所有叶子节点都在同一层上,这样的二叉树称为满二叉树。

如图为一颗满二叉树

满二叉树的特点

满二叉树的特点有:

  1. 叶子节点只能出现在最下一层。
  2. 非叶子结点的度一定是2。
  3. 在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。
  4. 设树的深度为i,则总结点数为 2^i -1
  5. 满二叉树是一种特殊的完全二叉树
  6. 若有双亲,则其双亲为i / 2,若有左孩子,则左孩子为2i ,若有右孩子,则右孩子为2i + 1 。

三、完全二叉树

定义

对二叉树节点由左至右由上至下的编号,如果编号为i的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。

如图为一颗完全二叉树

特点
  1. 叶子结点只能出现在最下层和次下层。
  2. 最下层的叶子结点集中在树的左部。
  3. 倒数第二层若存在叶子结点,一定在右部连续位置。
  4. 如果结点度为1,则该结点只有左孩子,即没有右子树。
  5. 同样结点数目的二叉树,完全二叉树深度最小。
  6. 满二叉树一定是完全二叉树,但反过来不一定成立。

四、二叉树的性质

  • 二叉树的第i层上至多有2^(i-1) (i≥1)个结点
  • 深度为k的二叉树至多有2^k-1个结点(k≥1)
  • 对任何一棵二叉树T,如果其终端结点数为N0,度为2的结点数为N2,则N0=N2+1
  • 具有n个结点的完全二叉树的深度为[log2(n)]+1
  • 一棵具有n个结点的完全二叉树(又称顺序二叉树)对其结点按层从上至下(每层从左至右)进行1-n的编号,则对任一结点i(1≤i≤n)有:
  • 若i>1,则i的双亲是[i/2];若i=1,则i是根,无双亲。
  • 若2i≤n,则i的左孩子是2i;否则,i无左孩子
  • 若2i+1≤n,则i的右孩子是2i+1;否则,i无右孩子

五、二叉树的储存结构

二叉树的储存结构分为顺序存储结构和链式存储结构

顺序存储结构

二叉树的顺序存储是指用一组地址连续的存储单元依次自上而下、自左至右存储完全二叉树上的结点元素,即将完全二叉树上编号为i ii的结点元素存储在一维数组下标为 i − 1的分量中。
依据二叉树的性质,完全二叉树和满二叉树采用顺序存储比较合适,树中结点的序号可以唯一地反映结点之间的逻辑关系,这样既能最大可能地节省存储空间,又能利用数组元素的下标值确定结点在二叉树中的位置,以及结点之间的关系。
但对于一般的二叉树,为了让数组下标能反映二叉树中结点之间的逻辑关系,只能添加一些并不存在的空结点,让其每个结点与完全二叉树上的结点相对照,再存储到一维数组的相应分量中。然而,在最坏情况下,一个高度为h 且只有h 个结点的单支树却需要占据近2h-1个存储单元。二叉树的顺序存储结构如图所示,其中0表示并不存在的空结点。



链式存储结构

由于顺序储存结构非常不便,所以我们通常采用链式存储结构实现二叉树。链式存储结构通过开辟一块空间(节点),通过指针储存左孩子、右孩子节点以及数据。

由于顺序结构操作起来并不方便,所以我们通常都以链式存储结构通过递归来实现二叉树,定义如下

typedef struct BinaryTree
{int val;struct BinaryTree *left;struct BinaryTree *right;
}BT;

六、二叉树的基本操作

  • CreateTree() :创建二叉树
  • PreOrder(BT* root):二叉树的前序遍历
  • InOrder(BT* root): 二叉树的中序遍历
  • BackOrder(BT* root): 二叉树的后序遍历
  • DestoryTree(BT* root):销毁二叉树
  • FindTree(BT* root, int x):查找二叉树中值为x的节点

七、二叉树的创建

如下是对二叉树进行创建的算法

BTNode* CreatNode(int x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL){perror("malloc fail");exit(-1);}node->val = x;node->left = NULL;node->right = NULL;return node;
}

八、二叉树的遍历

前序遍历

二叉树的前序遍历顺序为根 - 左 - 右

即先访问根节点

然后访问其左孩子节点

最后访问其右孩子节点

例如上图,前序遍历顺序为:A -> B -> D -> E -> C -> F 

算法如下

void PreOrder(BT* root)
{if (root == NULL){return;}printf("%d",root->val);PreOrder(root->left);PreOrder(root->right);
}

中序遍历

二叉树的前序遍历顺序为左 - 根 - 右

即先访问左孩子节点

然后访问其根节点

最后访问其右孩子节点

例如上图,前序遍历顺序为:D -> B -> E -> A -> F -> C 

算法如下

void InOrder(BT* root)
{if (root == NULL){return;}InOrder(root->left);printf("%d ", root->val);InOrder(root->right);
}

后序遍历

二叉树的前序遍历顺序为左 - 右 - 根

即先访问左孩子节点

然后访问其根节点

最后访问其右孩子节点

例如上图,前序遍历顺序为:D -> E -> B -> F -> C -> A

 算法如下

void BackOrder(BT* root)
{if (root == NULL){return;}BackOrder(root->left);BackOrder(root->right);printf("%d ", root->val);
}

九、二叉树的销毁

二叉树的销毁同样通过递归来实现:

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

十、二叉树中节点的查找

BT* FindTree(BT* root, int x)
{if (root == NULL){return;}if (root->val == x)return root;FindTree(root->left, x);FindTree(root->right, x);return NULL;
}

以上就是对二叉树的介绍以及基本操作的实现,各位老爷别忘了给个支持三连🌹🌹

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

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

相关文章

2016Outlook显示正在启动无法进入Outlook

2016Outlook显示正在启动无法进入Outlook 故障现象: 因上次非正常关闭,导致Outlook启动时,一直处于启动界面,无法进入主界面正常工作 故障截图: 故障原因: 数据文件异常导致 解决方案: 1、关…

【FPGA】正确处理设计优先级--或许能帮你节省50%的资源

概述 假如现在有一种方法–可以在不怎么需要修改已有设计的情况下,就可以帮您节省50%的设计资源,那你会试试看吗? 当前市场环境下,更低廉的成本却可获得同等性能无疑是极具诱惑的。本文将介绍一种FPGA设计技术,该技术…

数据结构—二叉树的模拟实现(c语言)

目录 一.前言 二.模拟实现链式结构的二叉树 2.1二叉树的底层结构 2.2通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 2.3二叉树的销毁 2.4二叉树查找值为x的节点 2.5二叉树节点个数 2.6二叉树叶子节点个数 2.7二叉树第k层节点个数 三.二叉树的遍历 3.1…

可怕!.Net 8正式发布了,.Net野心确实不小!

随着三天.NET Conf 2023的会议结束了,.Net 8正式发布了。 .Net 8是官方号称有史以来性能最快的一个版本了。 .Net 8 增加了数以千计的性能、稳定性和安全性改进,以及平台和工具增强功能,有助于提高开发人员的工作效率和创新速度。 反正就是…

无需数据库服务器部署脚本,全能型开源数据库监控平台lepus

Lepus 是一款开源的数据库监控平台,目前已经支持 MySQL、Oracle、SQLserver、MongoDB、Redis 等数据库的基本监控和告警。 Lepus 在监控数据库时,无需在每台数据库服务器上部署脚本或 Agent,只需要在数据库中创建授权账号后,即可…

2023.11.14 关于 Spring Boot 创建和使用

目录 Spring Boot Spring Boot 项目的创建 网页版创建 Spring Boot 项目 Spring Boot 目录说明 项目运行 Spring Boot Spring Boot 是基于 Spring 设计的一个全新的框架,其目的是用来简化 Spring 的应用、初始搭建、开发的整个过程Spring Boot 就是一个整合了…

CPD:使用restAPI和cpd-cli命令创建DMC实例

环境 Red Hat Enterprise Linux release 8.6 (Ootpa)OCP 4.12.22IBM CP4D 4.8.0Data Management Console 3.1.12 (DMC for CPD 4.8.0) 注:使用了fyre VM。 创建DMC实例 准备 首先export环境变量: . ./stg_env.sh把 cpd-cli 放到PATH里。编辑 ~/.ba…

Blackmagic Design DaVinci Resolve Studio18(达芬奇调色剪辑)mac/win中文版

在影视制作领域,调色和剪辑是至关重要的环节,它们直接决定了作品的观感和质量。而Blackmagic Design DaVinci Resolve Studio18(达芬奇调色剪辑)作为业界领先的专业调色剪辑软件,以其出色的性能和强大的功能&#xff0…

一文图解爬虫_姊妹篇(spider)

—引导语 爬虫,没有一个时代比当前更重视它。一个好的爬虫似乎可以洞穿整个互联网,“来装满自己的胃”。 接上一篇:一文图解爬虫(spider) 博主已初步对爬虫的“五脏六腑”进行了解剖。虽然俗称“爬虫”,但窃…

stm32超声波测距不准的解决方法(STM32 delay_us()产生1us)及stm32智能小车超声波测距代码(C语言版本)

首先要说明一下原理:使用stm32无法准确产生1us的时间,但是超声波测距一定要依赖时间,时间不准,距离一定不准,这是要肯定的,但是在不准确的情况下,要测量一个比较准确的时间,那么只能…

2023.11.16 hivesql之条件函数,case when then

目录 一.Conditional Functions条件函数 二.空值相关函数 三:使用注意事项 3.1 then后面不能接子查询 3.2 then后面只能是结果值 3.3 then后面能不能接两列 四.用于建表新增字段使用场景 一.Conditional Functions条件函数 -- 演示条件函数 -- if(条件判断,t…

如何检查 Docker 和 Kubernetes 是否可以访问外部网络,特别是用于拉取镜像的仓库?

要检查 Docker 和 Kubernetes 是否可以访问外部网络,尤其是用于拉取容器镜像的仓库,您可以按照以下步骤进行: 1. 检查节点的网络连接 首先,您需要确保 Kubernetes 节点能够访问外部网络。这可以通过在节点上执行 ping 命令来测试…