【学习总结】《大话数据结构》- 第6章-树

摘要:
大华数据结构-概述第6章树-代码链接启示:树目录6.1简介6.2树的定义6.3树的抽象数据类型6.4树的存储结构6.5二叉树的属性6.7二叉树存储结构6.8遍历二叉树6.9二叉树6.10线程二叉树6.1 1树与二叉树之间的转换6.12霍夫曼树及其应用程序6.13总结评论6.14结束语=========1====3====2===˃===0时,根节点是唯一的,并且不能有多个根节点。对于树中的每个节点,其子树的集合是林。

【学习总结】《大话数据结构》- 总

第6章树-代码链接

启示:

【学习总结】《大话数据结构》- 第6章-树第1张

目录

========================================

6.1 开场白
  • 一些可以略过的场面话...

========================================

6.2 树的定义
  • 定义

【学习总结】《大话数据结构》- 第6章-树第2张
【学习总结】《大话数据结构》- 第6章-树第3张

  • 注意:

    • n>0时:根节点是唯一的,不可能存在多个根节点。

    • m>0时:子树的个数没有限制,但它们一定互不相交。

  • 结点分类

    • 结点的度(degree):结点拥有的子树数

    • 叶结点(leaf)或终结点:度为0的结点

    • 非终端结点或分支结点:度不为0的结点

    • 内部结点:除根节点外,分支结点也称为内部结点

    • 树的度:树内各结点的度的最大值

【学习总结】《大话数据结构》- 第6章-树第4张

  • 结点间关系

    • 孩子(child):结点的子树的根称为该结点的孩子

    • 双亲(parent):该结点称为孩子的双亲(父母同体,唯一的一个)

    • 兄弟(sibling):同一个双亲的孩子之间互称兄弟

    • 祖先:结点的祖先是从根到该结点所经分支上的所有结点

    • 子孙:以某结点为根的子树中的任一结点都称为该节点的子孙

【学习总结】《大话数据结构》- 第6章-树第5张

  • 树的其他相关概念

    • 层次(level):从根开始定义起,根为第一层,根的孩子为第二层

      即:若某结点在第L层,则其子树的根就在第L+1层

    • 堂兄弟:双亲在同一层的结点互为堂兄弟

    • 深度(depth)或高度:树中结点的最大层次称为树的深度或高度

【学习总结】《大话数据结构》- 第6章-树第6张

  • 有序树/无序树:如果将树中结点的各子树看成从左至右有次序的,不能互换的,则称该树为有序树,否则为无序树。

  • 森林(forest):m(m>=0)棵互不相交的树的集合。

    • 对于树中每个结点而言,其子树的集合即为森林。

  • 线性表与树的对比

【学习总结】《大话数据结构》- 第6章-树第7张

========================================

6.3 树的抽象数据类型
  • 相比线性结构,树的操作就完全不同了。以下是基本和常用操作。

【学习总结】《大话数据结构》- 第6章-树第8张

========================================

6.4 树的存储结构
  • 简单的顺序存储结构无法直接反映逻辑关系,不能满足树的实现要求

    故充分利用顺序存储和链式存储结构的特点,介绍三种不同的表示法

  • 双亲表示法

    • 引入:除根节点外,其余每个结点,不一定有孩子,但一定有且仅有一个双亲

    • 定义:设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。

      • data:数据域,存储结点的数据信息

      • parent:指针域,存储该结点的双亲在数组中的下标

      • 约定:根节点的位置域为-1

【学习总结】《大话数据结构》- 第6章-树第9张

  • 代码实现:

【学习总结】《大话数据结构》- 第6章-树第10张
【学习总结】《大话数据结构》- 第6章-树第11张

  • 图示:

【学习总结】《大话数据结构》- 第6章-树第12张【学习总结】《大话数据结构》- 第6章-树第13张

  • 弊端:找一个结点的双亲,时间复杂度O(1),但是找一个结点的孩子,需要遍历整个结构

  • 针对上述找孩子的解决:增设一个结点最左边孩子的域(长子域),没有孩子的结点,长子域为-1

    • 2个孩子:知道长子是谁,另一个就是次子了

【学习总结】《大话数据结构》- 第6章-树第14张

  • 另一个问题:兄弟之间的关系 -- 增加一个右兄弟域来体现兄弟关系,没有右兄弟时为-1

【学习总结】《大话数据结构》- 第6章-树第15张

  • 同时关注结点的双亲、孩子、兄弟时:设置双亲域、长子域、右兄弟域

    但对时间遍历要求较高,有需要时再添加相应的结构

  • 孩子表示法

    • 多重链表表示法:

      • 每个结点有多个指针域,其中每个指针指向一棵子树的根节点,这种方法叫做多重链表表示法。

    • 方案一:设置指针域的个数为树的度

      • 可能存在空间的浪费

【学习总结】《大话数据结构》- 第6章-树第16张
【学习总结】《大话数据结构》- 第6章-树第17张
【学习总结】《大话数据结构》- 第6章-树第18张
【学习总结】《大话数据结构》- 第6章-树第19张

  • 方案二:设置每个结点指针域的个数等于该结点的度,取一个位置来存储结点指针域的个数

    • 空间利用率提高,但是各个结点的链表结构不同,要维护结点的度的数值,时间损耗提高

【学习总结】《大话数据结构》- 第6章-树第20张
【学习总结】《大话数据结构》- 第6章-树第21张
【学习总结】《大话数据结构》- 第6章-树第22张
【学习总结】《大话数据结构》- 第6章-树第23张

  • 孩子表示法:

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

【学习总结】《大话数据结构》- 第6章-树第24张
【学习总结】《大话数据结构》- 第6章-树第25张

  • 孩子表示法的两种结点结构

    • 孩子链表的孩子结点

【学习总结】《大话数据结构》- 第6章-树第26张
【学习总结】《大话数据结构》- 第6章-树第27张
- ### 表头数组的表头结点
【学习总结】《大话数据结构》- 第6章-树第28张
【学习总结】《大话数据结构》- 第6章-树第29张

  • 孩子表示法的结构定义代码:

【学习总结】《大话数据结构》- 第6章-树第30张
【学习总结】《大话数据结构》- 第6章-树第31张

  • 孩子表示法的弊端:找某结点的双亲,仍需要遍历整个树

  • 改进:双亲孩子表示法

【学习总结】《大话数据结构》- 第6章-树第32张

  • 孩子兄弟表示法

    • 引入:

      任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。

      因此,可以设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟

【学习总结】《大话数据结构》- 第6章-树第33张
【学习总结】《大话数据结构》- 第6章-树第34张

  • 结构定义代码:

【学习总结】《大话数据结构》- 第6章-树第35张

  • 图示:

【学习总结】《大话数据结构》- 第6章-树第36张
【学习总结】《大话数据结构》- 第6章-树第37张

  • 弊端:找双亲仍需遍历整棵树,可以增加parent指针域

  • 好处:把一棵复杂的树变成了一棵二叉树

【学习总结】《大话数据结构》- 第6章-树第38张

========================================

6.5 二叉树的定义
  • 定义

【学习总结】《大话数据结构》- 第6章-树第39张
【学习总结】《大话数据结构》- 第6章-树第40张

  • 1、二叉树的特点

【学习总结】《大话数据结构》- 第6章-树第41张
【学习总结】《大话数据结构》- 第6章-树第42张
【学习总结】《大话数据结构》- 第6章-树第43张
【学习总结】《大话数据结构》- 第6章-树第44张

  • 2、特殊二叉树

    • 1-斜树:

      所有结点都只有左子树的二叉树叫左斜树

      所有结点都只有右子树的二叉树叫右斜树

      这两者统称为斜树。

      特点:每层只有一个结点,结点个数与二叉树的深度相同

      注:线性表结构可以理解为是树的一种极其特殊的表现形式

【学习总结】《大话数据结构》- 第6章-树第45张【学习总结】《大话数据结构》- 第6章-树第46张

  • 2、满二叉树

    定义:一棵二叉树中,所有分支结点都存在左右子树,并且所有叶子都在同一层

【学习总结】《大话数据结构》- 第6章-树第47张
#### 特点:
【学习总结】《大话数据结构》- 第6章-树第48张

  • 3、完全二叉树

    • 定义:对一棵具有n个结点的二叉树按层序编号,如果编号i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则此二叉树为完全二叉树

      完全二叉树示例:

【学习总结】《大话数据结构》- 第6章-树第49张
#### 非完全二叉树示例:
【学习总结】《大话数据结构》- 第6章-树第50张
- #### 完全二叉树的特点:
【学习总结】《大话数据结构》- 第6章-树第51张
- #### 完全二叉树的判断方法:给每个结点按满二叉树的结构逐层排序,如果编号出现空档,就不是,否则就是。

========================================

6.6 二叉树的性质

【学习总结】《大话数据结构》- 第6章-树第52张
【学习总结】《大话数据结构》- 第6章-树第53张
【学习总结】《大话数据结构》- 第6章-树第54张
【学习总结】《大话数据结构》- 第6章-树第55张

  • 推导:

【学习总结】《大话数据结构》- 第6章-树第56张
【学习总结】《大话数据结构》- 第6章-树第57张
【学习总结】《大话数据结构》- 第6章-树第58张

【学习总结】《大话数据结构》- 第6章-树第59张
【学习总结】《大话数据结构》- 第6章-树第60张

  • 简单推导:

【学习总结】《大话数据结构》- 第6章-树第61张
【学习总结】《大话数据结构》- 第6章-树第62张

【学习总结】《大话数据结构》- 第6章-树第63张
【学习总结】《大话数据结构》- 第6章-树第64张
【学习总结】《大话数据结构》- 第6章-树第65张

  • 举例:

【学习总结】《大话数据结构》- 第6章-树第66张
【学习总结】《大话数据结构》- 第6章-树第67张

========================================

6.7 二叉树的存储结构
  • 二叉树的顺序存储结构:按完全二叉树编号

    • 顺序存储结构一般只用于完全二叉树,否则容易造成空间的浪费

    • 完全二叉树:

【学习总结】《大话数据结构》- 第6章-树第68张
【学习总结】《大话数据结构》- 第6章-树第69张

  • 一般二叉树:

【学习总结】《大话数据结构》- 第6章-树第70张

  • 极端情况的二叉树:

【学习总结】《大话数据结构》- 第6章-树第71张

  • 二叉链表

    • 定义:

      二叉树每个结点最多有两个孩子,所以设置一个数据域和两个指针域,这样的链表称为二叉链表。

【学习总结】《大话数据结构》- 第6章-树第72张
- data:数据域
- lchild和lchild:指针域,分别存放指向左孩子和右孩子的指针。

  • 二叉链表的结点结构定义代码

【学习总结】《大话数据结构》- 第6章-树第73张

  • 图示:

【学习总结】《大话数据结构》- 第6章-树第74张

  • 三叉链表:

    • 如有需要,可增加一个指向其双亲的指针域,其称为三叉链表。

========================================

6.8 遍历二叉树
  • 二叉树遍历原理

【学习总结】《大话数据结构》- 第6章-树第75张

  • 关键词:访问和次序

  • 访问:根据实际的需求来确定具体做什么,算作是一个抽象操作。

  • 遍历次序:

    • 线性结构最多是从头到尾、循环、双向等。

    • 树节点不存在唯一前驱后继,会因为遍历方式不同而产生完全不同的结果。

  • 二叉树遍历方法:

    • 四种:前序遍历、中序遍历、后序遍历、层序遍历。

    • 前序遍历:根左右

【学习总结】《大话数据结构》- 第6章-树第76张
【学习总结】《大话数据结构》- 第6章-树第77张

  • 中序遍历:左根右

【学习总结】《大话数据结构》- 第6章-树第78张
【学习总结】《大话数据结构》- 第6章-树第79张

  • 后序遍历:左右根

【学习总结】《大话数据结构》- 第6章-树第80张
【学习总结】《大话数据结构》- 第6章-树第81张

  • 层序遍历:

【学习总结】《大话数据结构》- 第6章-树第82张
【学习总结】《大话数据结构》- 第6章-树第83张

  • 前序遍历

    • 代码实现;

【学习总结】《大话数据结构》- 第6章-树第84张

  • 图示:

【学习总结】《大话数据结构》- 第6章-树第85张
【学习总结】《大话数据结构》- 第6章-树第86张
【学习总结】《大话数据结构》- 第6章-树第87张
【学习总结】《大话数据结构》- 第6章-树第88张
【学习总结】《大话数据结构》- 第6章-树第89张
【学习总结】《大话数据结构》- 第6章-树第90张
【学习总结】《大话数据结构》- 第6章-树第91张
【学习总结】《大话数据结构》- 第6章-树第92张
【学习总结】《大话数据结构》- 第6章-树第93张
【学习总结】《大话数据结构》- 第6章-树第94张

  • 中序遍历

    • 代码实现

【学习总结】《大话数据结构》- 第6章-树第95张

  • 图示:

【学习总结】《大话数据结构》- 第6章-树第96张
【学习总结】《大话数据结构》- 第6章-树第97张
【学习总结】《大话数据结构》- 第6章-树第98张
【学习总结】《大话数据结构》- 第6章-树第99张
【学习总结】《大话数据结构》- 第6章-树第100张
【学习总结】《大话数据结构》- 第6章-树第101张
【学习总结】《大话数据结构》- 第6章-树第102张
【学习总结】《大话数据结构》- 第6章-树第103张
【学习总结】《大话数据结构》- 第6章-树第104张

  • 后序遍历

    • 代码实现:

【学习总结】《大话数据结构》- 第6章-树第105张

  • 图示:

【学习总结】《大话数据结构》- 第6章-树第106张
【学习总结】《大话数据结构》- 第6章-树第107张

  • 遍历推导

    • 已知前序遍历和中序遍历,求后序遍历

      前序:ABCDEF,中序:CBAEDF

      • 前序第一个字母是A,说明A是根节点
      • 中序CBAEDF,说明CB在A的左,EDF在A的右
        【学习总结】《大话数据结构》- 第6章-树第108张
      • 前序CB:ABCDEF,先B后C,故B是A的左,C是B的孩子,左右不确定
      • 中序CB:CBAEDF,先C后B,故C是B的左
        【学习总结】《大话数据结构》- 第6章-树第109张
      • 前序EDF:ABCDEF,说明D是A的右孩子,EF是D的子孙
      • 中序EDF:CBAEDF,E在D左,F在D右,说明E是D的左孩子,F是D的右孩子
        【学习总结】《大话数据结构》- 第6章-树第110张
      • 根据得到的二叉树图,检查一下是否符合所给前序和中序
      • 然后可得后序:CBEFDA
    • 已知中序遍历和后序遍历,求前序遍历:

【学习总结】《大话数据结构》- 第6章-树第111张

  • 性质小结:

【学习总结】《大话数据结构》- 第6章-树第112张
【学习总结】《大话数据结构》- 第6章-树第113张

========================================

6.9 二叉树的建立
  • 二叉树的扩展二叉树:

    • 为了能让每个结点确认是否有左右孩子,将每个结点的空指针引出一个虚结点,其值为一特定值,比如"#"

    • 称这种处理后的二叉树为原二叉树的扩展二叉树

    • 扩展二叉树就可以做到一个遍历序列确定一棵二叉树

【学习总结】《大话数据结构》- 第6章-树第114张

  • 代码实现:

【学习总结】《大话数据结构》- 第6章-树第115张
【学习总结】《大话数据结构》- 第6章-树第116张

  • 其他:

    • 当然,也可以用中序或后序遍历的方式实现二叉树的建立

      只需对代码里生成结点和构造左右子树的代码顺序交换,并且输入字符也做相应的更新即可。

========================================

6.10 线索二叉树
  • 引入:

    • 空指针存在空间的浪费

【学习总结】《大话数据结构》- 第6章-树第117张

  • 二叉链表中,只能看出左右孩子,而看不出某序遍历的前驱和后继

  • 定义:

    • 线索:指向前驱和后继的指针称为线索

    • 线索链表:加上线索的二叉链表称为线索链表

    • 线索二叉树(Threaded Binary Tree):相应的二叉树称为线索二叉树

【学习总结】《大话数据结构》- 第6章-树第118张
【学习总结】《大话数据结构》- 第6章-树第119张

  • 线索化:对二叉树以某种次序遍历使其变为线索二叉树的过程

【学习总结】《大话数据结构》- 第6章-树第120张
(此处应该是把非空指针域也变成了线索)

  • 为区分左右孩子和前驱后继,每个结点增设两个标志域

(注:此标志域占用的内存空间小于rchild类的指针变量)
【学习总结】《大话数据结构》- 第6章-树第121张
【学习总结】《大话数据结构》- 第6章-树第122张
【学习总结】《大话数据结构》- 第6章-树第123张

  • 线索二叉树的结构实现

【学习总结】《大话数据结构》- 第6章-树第124张

  • 前驱和后继的信息只有在遍历二叉树时才能得到

  • 所以线索化的过程就是在遍历的过程中修改空指针的过程。

  • 代码实现:中序遍历线索化

【学习总结】《大话数据结构》- 第6章-树第125张
【学习总结】《大话数据结构》- 第6章-树第126张
【学习总结】《大话数据结构》- 第6章-树第127张

  • 类双向链表图示:

【学习总结】《大话数据结构》- 第6章-树第128张

  • 类双向链表代码实现:

【学习总结】《大话数据结构》- 第6章-树第129张
【学习总结】《大话数据结构》- 第6章-树第130张
【学习总结】《大话数据结构》- 第6章-树第131张
【学习总结】《大话数据结构》- 第6章-树第132张

========================================

6.11 树、森林与二叉树的转换
  • 树转换为二叉树

【学习总结】《大话数据结构》- 第6章-树第133张
【学习总结】《大话数据结构》- 第6章-树第134张

  • 森林转换为二叉树

【学习总结】《大话数据结构》- 第6章-树第135张
【学习总结】《大话数据结构》- 第6章-树第136张

  • 二叉树转换为树

【学习总结】《大话数据结构》- 第6章-树第137张
【学习总结】《大话数据结构》- 第6章-树第138张
【学习总结】《大话数据结构》- 第6章-树第139张

  • 二叉树转换为森林

    • 首先判断:二叉树的根结点是否有右孩子:有就是森林,否则不是。

    【学习总结】《大话数据结构》- 第6章-树第140张
    【学习总结】《大话数据结构》- 第6章-树第141张

  • 树和森林的遍历

【学习总结】《大话数据结构》- 第6章-树第142张
【学习总结】《大话数据结构》- 第6章-树第143张
【学习总结】《大话数据结构》- 第6章-树第144张
【学习总结】《大话数据结构》- 第6章-树第145张
【学习总结】《大话数据结构》- 第6章-树第146张
【学习总结】《大话数据结构》- 第6章-树第147张

========================================

6.12 赫夫曼树及其应用
  • 定义

【学习总结】《大话数据结构》- 第6章-树第148张

  • 路径:从树中一个结点到另一个结点之间的分支构成两个结点之间的路径

  • 路径长度:路径上的分支数目称为路径长度

  • 树的路径长度:从树根到每个结点的路径长度(注意是每一结点,不止是所有叶结点)

    树a的路径长度:【学习总结】《大话数据结构》- 第6章-树第149张

    树b的路径长度:【学习总结】《大话数据结构》- 第6章-树第150张

  • 结点的带权路径长度:从该结点到树根之间的路径长度与结点上权值的乘积。

  • 树的带权路径长度:树中所有叶子结点的带权路径长度。(注意是叶子结点,没有中间的)

  • 赫夫曼树(Huffman):带权路径长度WPL最小的二叉树称做赫夫曼树。也叫最优二叉树。

    • 注:哈夫曼树中没有度为1的结点。(每一个结点都是由它的两棵子树合并产生的新结点)

【学习总结】《大话数据结构》- 第6章-树第151张
【学习总结】《大话数据结构》- 第6章-树第152张

  • 构造最优的赫夫曼树

【学习总结】《大话数据结构》- 第6章-树第153张
【学习总结】《大话数据结构》- 第6章-树第154张

  • 构造赫夫曼树的赫夫曼算法描述:

【学习总结】《大话数据结构》- 第6章-树第155张

  • 赫夫曼编码

【学习总结】《大话数据结构》- 第6章-树第156张
【学习总结】《大话数据结构》- 第6章-树第157张
【学习总结】《大话数据结构》- 第6章-树第158张
【学习总结】《大话数据结构》- 第6章-树第159张

========================================

6.13 总结回顾

========================================

6.14 结尾语

END

免责声明:文章转载自《【学习总结】《大话数据结构》- 第6章-树》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SocketChannel简述Java Bean Validation 最佳实践下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

logic:iterate 遍历

1. 遍历集合 <logic:iterate> 的 name 属性指定需要进行遍历的集合对象, 它每次从集合中检索出一个元素, 然后把它放在page 范围内, 并以id 属性指定的字符串来命名这个元素, 例如: <% Vector animals = new Vector(); animals.addElement("Dog"); ani...

算法总结—深度优先搜索DFS

深度优先搜索(DFS) 往往利用递归函数实现(隐式地使用栈)。 深度优先从最开始的状态出发,遍历所有可以到达的状态。由此可以对所有的状态进行操作,或列举出所有的状态。 1.poj2386 Lake Couting 题意:八连通被认为连接在一起,求总共有多少个水洼? Sample Input: 10 12 W........WW. .WWW.....WWW...

长沙社区团购独角兽《兴盛优选》 18k 面试题记录,已拿offer!

长沙或者想从北上广大回长沙的小伙伴,应该都听说过《兴盛优选》,一家位于长沙市从事社区团购业务的独角兽企业。 目前日订单1000+万,在长沙薪资也较有诱惑力,要不要来挑战一下? 我在里面潜伏过一段时间,发现里面缺人非常严重,大家都知道长沙互联网发展的晚,目前《兴盛优选》的招人要求也比较高(相对长沙其他企业),所以招到满意的人非常少,100份简历可能只能进1到...

0x01 译文:Windows桌面应用Win32开发简介

本节课将简单介绍下使用C++开发Windows桌面应用的一些基础知识  目录: 准备你的开发环境 Windows 代码规范 操作字符串 什么是一个Window? WinMain:程序的入口点 1. 准备你的开发环境 安装 Windows SDK        要用C或者C++开发Windows 程序,你必须安装 Microsoft Windows So...

《C++ Qt设计模式》 第一章 C++ 简介

第1 章 C++简介 内容: 编译相关     Qt提供了一个qmake工具,它会产生Makefile 文件。使用qmake -project 命令产生一个简单的工程文件。当执行这个命令时,qmake 会将当前工作目录下的全部源文件作为SOURCES列出来,而将全部头文件作为HEADERS 列出来     使用make 重新编译那些发生了变化的文件,或...

使用json数据动态创建表格2(多次绘制第一次简化 var tr=tbody.insertRow();)

<!DOCTYPE HTML> <html> <head> <title>动态创建表格</title> <meta charset="utf-8" /> <style> table{width:600px; border-collapse:collapse;...