算法:什么是树以及树相关概念

树的定义

  • 树是用来处理一对多的数据结构
  • 树是n(n>=0)个节点的有限集
    • n = 0, 叫做空树
    • n > 0:
      • 根节点是唯一的
      • 子树的个数没有限制,但是一定是不相交的
        在这里插入图片描述
  • 这里面每个元素我们叫作“节点”;用来连线相邻节点之间的关系,我们叫作“父子关系”。

树的度

  • 节点拥有的子树数量称为节点的度 。 根据各个节点的度的不同,节点可以分为:

    • 叶子节点(Leaf) [也叫做终端节点]: 度为0的节点
    • 分支节点[也叫做非终端节点]: 度不为0
      • 内部节点: 除了根节点之外,分支节点也叫做内部节点
  • 树的度是树内各节点的度的最大值
    在这里插入图片描述

节点间关系

  • 当前节点的子树的根称为该节点的孩子(子节点)
  • 当前节点称为其子节点的双亲 【因为当前节点只有一个,所以叫做双亲节点,而不是父/母节点】
  • 同一个双亲的孩子之间互称为兄弟
  • 节点的祖先从根节点到当前节点所经分支上的所有节点。 比如下图, 相对于H节点,D,B,A都是它的祖先
  • 以某节点为根的子树中任一节点都称为该节点的子孙。比如B的子孙有D,G,H,I
    在这里插入图片描述
    比如下面这幅图,A 节点就是 B 节点的父节点,B 节点是 A 节点的子节点。B、C、D 这三个节点的父节点是同一个节点,所以它们之间互称为兄弟节点。我们把没有父节点的节点叫作根节点,也就是图中的节点 E。我们把没有子节点的节点叫作叶子节点或者叶节点,比如图中的 G、H、I、J、K、L 都是叶子节点。
    在这里插入图片描述

树的层

  • 节点的层(level): 从根节点开始,根节点为第一层,跟的孩子为第二层。。。 若某节点为第i层,则其子树的跟就在第i+1层
  • 其双亲在同一层的节点互为堂兄弟。 比如下图中的,D,E,F是堂兄弟,G,H,I,J是堂兄弟
  • 树中节点的最大层次称为树的深度。比如下图中树的深度为4
    在这里插入图片描述

高度(Height)、深度(Depth)、层(Level)这三个概念比较难以区分,它们的定义是这样的:

在这里插入图片描述
举个例子:
在这里插入图片描述

如何记忆:

  • 在我们生活中,“高度”这个概念,其实就是从下往上度量,比如我们要度量第 10 层楼的高度、第 13 层楼的高度,起点都是地面。所以,树这种数据结构的高度也是一样,从最底层开始计数,并且计数的起点是0
  • “深度”这个概念在生活中是从上往下度量的,比如水中鱼的深度,是从水平面开始度量的。所以,树这种数据结构的深度也是类似的,从根结点开始度量,并且计数起点也是 0。
  • “层数”跟深度的计算类似,不过,计数起点是 1,也就是说根节点的位于第 1 层。

树的有序性

如果树中结点的各子树从左向右是有序的,子树间不能互换位置,则称该树为有序树,否则为无序树。

树的表示方法

双亲表示法

取一块连续的内存空间,在层次每个节点的同时,各自都附加一个记录其父节点位置的变量

  • 在树结构中,除了树根外,每个结点都只有一个父结点(又叫“双亲结点”)。
#define tree_size 100//宏定义树中结点的最大数量
#define TElemType int//宏定义树结构中数据类型
typedef struct PTNode{ //节点结构
    TElemType data;//节点数据
    int parent;//双亲位置下标
}PTNode;
typedef struct {  // 树结构
    PTNode nodes[tree_size];//节点数组
    int r,n;//根的位置下标和结点数
}PTree;

例如,使用双亲表示法存储图 1(A)中的树结构时,数组存储结果为(B):

在这里插入图片描述

当算法中需要在树结构中频繁地查找某结点的父结点时,使用双亲表示法最合适。当频繁地访问结点的孩子结点时,双亲表示法就很麻烦,采用孩子表示法就很简单

孩子表示法

孩子表示法: 把每个节点的孩子节点排列起来,以单链表作存储结构,则n个节点有n个孩子链表,如果是叶子节点则单链表为空。然后n个头指针有组成一个线性表,采用顺序存储结构,存放进一个一维数组中

#define TElemType int
#define Tree_Size 100
//孩子表示法
typedef struct CTNode{
    int child;//链表中每个结点存储的不是数据本身,而是数据在数组中存储的位置下标
    struct CTNode * next;
}*ChildPtr;
typedef struct {
    TElemType data;//结点的数据类型
    ChildPtr firstchild;//孩子链表的头指针
}CTBox;
typedef struct{
    CTBox nodes[Tree_Size];//存储结点的数组
    int n,r;//结点数量和树根的位置
}CTree;

使用孩子表示法存储的树结构,正好和双亲表示法相反,适用于查找某结点的孩子结点,不适用于查找其父结点。
在这里插入图片描述

双亲孩子表示法

将双亲表示法和孩子表示法结合起来
在这里插入图片描述

孩子兄弟表示法

使用链式存储结构存储普通树。链表中每个结点由 3 部分组成:
在这里插入图片描述
其中孩子指针域,表示指向当前结点的第一个孩子结点,兄弟结点表示指向当前结点的下一个兄弟结点。

#define ElemType int
typedef struct CSNode{
    ElemType data;
    struct CSNode * firstchild,*nextsibling;
}CSNode,*CSTree;

通过孩子兄弟表示法,普通树转化为了二叉树,所以孩子兄弟表示法又被称为“二叉树表示法”或者“二叉链表表示法”。
在这里插入图片描述

常见树

在这里插入图片描述

  • 二叉搜索树的节点放置规则是: 任何节点的键值一定大于其左子树中的每一个节点的键值,并小于其右子树中的每一个节点的键值。因此:
    • 从根节点一直往左走,直到无左路可走,就可以得到最小元素
    • 从根节点一直往右走,直到无右路可走,就可以得到最大元素
  • 二叉搜索树(binary search tree)可以提供对数时间的元素插入和访问。
    • 访问元素很简单
    • 麻烦的是插入和删除

平衡二叉搜索树

  • 如果输入值不够随机,或者经过某些插入和删除操作,二叉搜索数可能会失去平衡,导致效率低下。
  • 为此,引入了平衡二叉树,包括AVL-tree、RB-tree、AA-tree等。

比较

树与线性表

在这里插入图片描述

树与森林

一棵树为树,两棵树及以上则称为森林
在这里插入图片描述

总结

树相关概念

  • 树由节点(node)和边(edge)构成
  • 整棵树有一个最上端节点,叫做根节点(root)
  • 每个节点可以可以拥有具有方向性的边(directed edges),用来和其他节点相连。
  • 相连节点中,在上面的叫做父节点(parent),在下面的叫做子节点(child)。
  • 没有子节点的叫做叶节点(leaf)
  • 子节点可以存在多个,如果最多只有两个子节点,那么就是二叉树
  • 不同的节点如果拥有相同的父节点,那么彼此互为兄弟节点(siblings)
  • 根节点到任何节点之间有唯一路径(path),路径所经过的边数,叫做路径长度(length)
  • 跟节点到任意节点的路径长度,为该节点的深度(depth)。根节点的深度永远是0
  • 某节点到最深子节点(叶节点)的路径长度,叫做该节点的高度(height)。整颗树的高度,以根节点的高度来代表。

在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值