数据结构——树

1.树的定义

树是一种非线性的数据结构,是由有限个结点组成的具有层次关系的集合,形状看起来像一棵倒挂的树,因此叫做树。

树具有一个特殊的结点,叫做根节点,该结点没有前驱结点。除根节点外,其他结点有且仅有一个前驱结点,有零个或者多个后继结点。这些结点又被分为若干颗树,每棵树没有交集,每棵树又被分为根节点和子树。因此,树是递归定义的。

如下图,就是一棵树。

在这里插入图片描述

2.树的有关概念

有关概念用下图进行举例
在这里插入图片描述
结点的度:结点具有的子树的个数。图中A结点的度为6,B、C结点的度为0。
叶子结点:也称为终端结点,指的是度为0的结点。图中B、C、P、Q等就是叶子结点
树的度:最大的结点的度为树的度。图中树的度为6。
双亲结点:若这个结点有子树,那么这个结点为子节点的双亲结点。图中A为B的双亲结点。D为H的双亲结点。
孩子结点:结点的子树的根节点为该结点的孩子结点。图中C、D为A的孩子结点,J为E的孩子结点。
兄弟结点:具有相同的双亲结点互称为兄弟结点。图中D、E互为兄弟结点。
结点的层次:根节点为第一层,子树的根节点第二层,依次类推。P、Q层次为4
结点的深度或高度:最大的结点的层次。图中树的高度为4。
堂兄弟结点:同一层的结点互为堂兄弟结点。
森林:若干棵不相交的树的集合。

3.树的表示

树的表示有很多方法,如双亲表示法,孩子表示法,左孩子右兄弟表示法。

这里就介绍一种常用的左孩子右兄弟表示法。
方法的意思是,定义一个结构体类型,内有两个指针域,一个指针指向自己的第一个孩子结点,另一个指针指向自己的兄弟结点。

在这里插入图片描述
定义一个结构体类型

typedef int DataType;
struct Node
{
 struct Node* firstChild; // 第一个孩子结点
 struct Node* NextBrother; // 指向其下一个兄弟结点
 DataType data; // 结点中的数据域
};

该树的存储结构如下图

在这里插入图片描述
如果该结点没有孩子或者兄弟,指针指向NULL;

4.二叉树的概念和结构

概念:每个结点的度都不大于2的树称为二叉树。

二叉树分为根、左子树和右子树;左、右子树又分为根、左子树和右子树,以此类推。

如图就是一棵二叉树。
在这里插入图片描述
此外任意二叉树都是有以下几种情况组合而成。
在这里插入图片描述

4.1特殊的二叉树

4.1.1完全二叉树

假如二叉树的高度为n,如果前n-1层的结点是满的,最后一层的结点从左到右是连续的,那么这种二叉树又称为完全二叉树。

下图就是一棵完全二叉树。前三层结点是满的,最后一层结点是连续的。
在这里插入图片描述

下图不是完全二叉树,因为第三层第一个结点没有左树。
在这里插入图片描述

此外,还需要知道一些二叉树的性质。

性质1:二叉树第n层的最大结点个数为2^(n-1)。
性质2:若二叉树的高度为n,那么该树最多有2^n-1个结点。
性质3:对于任意一棵二叉树,假设度为0的结点为n0,度为2的结点为n2,那么就有n0=n2+1;
性质4:对于完全二叉树,如果从上到下,从左到右依次对结点进行编号,根节点从0开始,那么假设结点的编号为n,则左孩子编号为2*n+1,右孩子编号为2*n+2;假设结点的编号为m,那么该结点的双亲结点编号为(m-1)/2。

关于性质3的证明。如下图

假设度为0的结点个数为n0,度为1的结点个数为n1,度为2的结点个数为n2
在这里插入图片描述
只有一个结点时n0=1,n2=0。满足n0=n2+1。

当增加结点时,会增加一个度为0的结点和一个度为1的结点,同时减少一个度为0的结点,此时增加的结点在叶子结点上。这种情况不会影响n0和n2的值。

当增加的结点不在叶子结点上,那么只能在度为1的结点上,此时会减少一个度为1的结点,增加一个度为2的结点,同时也会增加一个度为0的结点。n0和n2都增加一个,等式不变。

4.1.2满二叉树

二叉树的每一层的结点个数都达到最大值时,该二叉树称为满二叉树。

当完全二叉树的最后一层的结点个数达到该层最大结点数时,又称为满二叉树。
所以满二叉树是完全二叉树,完全二叉树不一定是满二叉树。

下图就是一课满二叉树。
在这里插入图片描述

5.二叉树的存储

5.1顺序存储

对于一棵普通二叉树,不适合使用顺序存储,因为会造成大量的空间浪费。顺序存储只适用于完全二叉树。

5.2链式存储

链式存储分为二叉链和三叉链。

二叉链:结构体内有两个指针变量,分别指向左孩子结点和右孩子结点。

结构体定义如下

typedef int BTDataType;

struct BinaryTreeNode
{
 struct BinTreeNode* Left; // 指向当前节点的左孩子
 struct BinTreeNode* Right; // 指向当前节点的右孩子
 BTDataType data; // 当前节点值域
}

在这里插入图片描述

三叉链:结构体内有三个指针,分别指向左右孩子结点和双亲结点。

结构体定义如下

struct BinaryTreeNode
{
 struct BinTreeNode* _pParent; // 指向当前节点的双亲
 struct BinTreeNode* _pLeft; // 指向当前节点左孩子
 struct BinTreeNode* _pRight; // 指向当前节点右孩子
 BTDataType _data; // 当前节点值域
}

在这里插入图片描述

二叉树的存储,对于顺序存储会介绍一个叫做堆的数据结构。链式存储会介绍它的实现以及各个接口和题目。

关于树的部分知识就介绍到这里了。

相关推荐

  1. 数据结构

    2024-04-01 06:10:02       39 阅读
  2. 数据结构-(C++)

    2024-04-01 06:10:02       39 阅读
  3. 数据结构】平衡

    2024-04-01 06:10:02       23 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-01 06:10:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-01 06:10:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-01 06:10:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-01 06:10:02       20 阅读

热门阅读

  1. 排序算法笔记

    2024-04-01 06:10:02       19 阅读
  2. 文件系统 FTP Ubuntu 安装入门介绍

    2024-04-01 06:10:02       19 阅读
  3. SOA、分布式、微服务之间的关系?

    2024-04-01 06:10:02       16 阅读
  4. 深入探索语言模型:原理、应用与评估

    2024-04-01 06:10:02       17 阅读
  5. 设计模式(11):适配器模式

    2024-04-01 06:10:02       19 阅读
  6. 2024.2.1力扣每日一题——数字游戏

    2024-04-01 06:10:02       16 阅读
  7. Vue企业级项目开发axios

    2024-04-01 06:10:02       20 阅读