文章目录

  • 定义
  • 树的存储结构
  • 树、森林与二叉树相互转换
  • 树的遍历
  • Huffman树
    • 二叉编码树
    • Huffman编码
  • 参考

定义

是由一个集合以及在该集合上定义的一种关系构成的。集合中元素成为树的结点,所定义的关系称为父子关系。当集合为空时,是一棵空树;当集合非空时,此时有且仅有一个特定的称为的结点。
如下图所示,a是一棵空树,b是只有一个根节点的树,c是一棵有10个结点,并且高度为2的树。

森林是m棵互不相交的树的集合。对树中的每个结点而言,其子树的集合即为森林。删去一棵树的根,就得到一个森林。反之,加上一个结点作为树根,森林就变为一棵树。

树的存储结构

1、双亲表示法:用一个一维数组存储每个结点,数组的下标就是结点的指针位置,每个结点包括一个数据与与指向父亲结点的数组下标的域。

在这种表示法下,寻找一个结点的父结点只需要O(1)时间。而查询儿子或者兄弟结点的操作可能需要遍历整个数组。
为了节省查询时间,可以规定儿子的数组下标值大于父亲数组下标值,而兄弟结点的数组小标志随着兄弟从左到右递增。如上图所示。


2、孩子链表表示法:用一个线性表来存储树的所有结点信息,称为结点表。每个结点建立一个孩子表,孩子表中只存储孩子结点的地址信息(可以是指针、数组下标或者内存地址)。

上图中的孩子表是用单链表来实现的。由于每个结点的孩子数目不确定,所以一般不用数组来实现孩子表,但是可以用数组实现结点表。
在孩子链表表示法中,通过某个结点找到其孩子比较容易,只需要遍历孩子链表即可。
然而要找到某个结点的父结点,却需要对每个结点的孩子链表进行遍历,比较麻烦,因此可以在孩子链表表示法的基础上结合双亲表示法,在每个结点域中附设一个指向双亲结点的域。如下图所示。


3、孩子兄弟表示法:又称二叉树表示法,每个结点除了数据域外,还包含第一个孩子和右邻兄弟。如下图所示,B的第一个孩子是D,B的兄弟结点是C。


树、森林与二叉树相互转换

通过树的孩子兄弟表示法可以看到,树和二叉树都可以使用二叉链表作为存储结构,因此从二叉链表可以推导出树与二叉树之间的一个对应关系,从实际存储来看,它们二叉链表相同,只是解释不同而已。

1、树转化二叉树
(1)顺序连接同一结点的兄弟结点;
(2)保留每个结点到其第一个孩子结点的连接作为该结点的左孩子结点,删除这个结点到其他孩子结点的连接;
(3)以树的根结点为中心,顺时针旋转一定角度,使得结构层次分明。
2、森林是若干树的集合,森林转化为二叉树
(1)将森林中的每一刻树转换为相应的二叉树;
(2)将第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树根结点的右孩子,得到二叉树。

3、二叉树还原为树或森林
按层次序列对二叉树的每个结点做以下操作:
(1)如果是根结点或者是左孩子结点,则不做任何改动;
(2)如果是右孩子,将其当前父亲的父亲设置为当前结点的父结点,若其当前父亲的父亲为空,则改动后其父亲为空。

树的遍历

由树的定义可以得到两种次序遍历树的方法:
(1)先序遍历:访问树的根结点;从左到右,依次先序遍历根的每棵子树。
(2)后序遍历:从左到右,依次后序遍历根的每棵子树;访问树的根结点。
森林的遍历
(1)先序遍历:访问森林第一棵树的根结点;先序遍历第一棵树中根结点的子树树林;先序遍历除去第一棵树后剩余的树构成的森林。上图中森林的先序遍历:ADBEFGCHI
(2)中序遍历:中序遍历第一棵树中根结点的子树树林;访问森林中第一棵树的根结点;中序遍历除去第一棵树后剩余的树构成的森林。上图中森林的中序遍历:DAEFGBHIC
(3)后序遍历:中序遍历第一棵树中根结点的子树树林;中序遍历除去第一棵树后剩余的树构成的森林;访问森林中第一棵树的根结点。上图中森林的后序遍历:DGEFIHCBA

由于树可以看作只有一棵树的森林,所以树的先序遍历和后序遍历分别与森林的先序遍历和中序遍历对应。

而森林的先序。中序、后序遍历与其相对应的二叉树的先序、中序、后序遍历结果相同,因此树的先序和后序遍历可以借助相应二叉树的先序遍历和中序遍历的算法实现。

由先序和中序遍历序列可以唯一确定一棵二叉树;由中序和后序遍历序列可以唯一确定一棵二叉树,但是由先序和后序不能唯一确定一棵二叉树。

例如:先序遍历为:EBADCFHG,中序序列为:ABCDEFGH,可确定二叉树为:

Huffman树

定义:给定N个权值作为叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的树为哈夫曼树,也称最优树。


左边树带权路径长度:(2+3+6+9)2=40
右边树带权路径长度:9 + 6
2 +(2+3)*3 = 36

构造哈夫曼树
输入:给定n个权值
构造n棵只有一个根结点的二叉树,n个权值分别是这些二叉树根结点的权,F是由这n棵二叉树构成的集合
重复执行:
选取两个最小的实数结点作为二叉树的左右结点,构造新的二叉树,然后根结点为权值之和;
将这两个结点从集合F中删除,加入新构造的树。

二叉编码树

符号数据在处理之前需要对符号进行二进制编码,例如英文字符的ASCII编码,它使用固定的8为二进制位表示字符,因此是一种定长编码。

为了缩短数据编码长度,可以以采用不定长编码:给使用频度较高的字符编较短的码,这是数据压缩技术的最基本思想。

那么如何给字符进行不定长编码,而使得数据编码的平均长度最短?使用二叉树对字符集中的字符进行编码,方法如下:
(1)将字符集中的所有字符作为二叉树的叶子结点;
(2)每一个“父亲-左孩子”关系对应一位二进制位0,每一个“父亲-右孩子”关系对应一位二进制1;
(3)从根通往每个叶子结点的路径,就对应于相应字符的二进制编码


A:0,B:100,C:11,D:101
二叉树编码得到的都是前缀编码,前缀编码使得不定长编码在解码过程中不会产生歧义

Huffman编码

对同一个字符集进行编码的二叉树可以有很多,但是哪个编码才是使得编码长度最小的呢?

由于字符集中各种字符出现的概率不同,字符的出现概率决定了编码方案的选择。
其实这将最佳编码方案抽象成为求带权路径长度最小的二叉树,而Huffman树就是这样的树。

参考

数据结构与算法(Java语言版)——周鹏
如有侵权,请联系作者更正

数据结构——树和森林相关推荐

  1. python链表和树实验报告_数据结构树和森林实验报告

    _ 树和森林应用实验 实验报告 实验目的 ( 1) 掌握树和森林的二叉链表表示方法. (2) 掌握树和二叉树的结构及算法之间的对应关系. (3) 掌握树的两种遍历算法及其应用. 实验运行环境 Visu ...

  2. 数据结构——树、森林和二叉树之间的转换

    摘自大佬博客http://www.cnblogs.com/zhuyf87/archive/2012/11/04/2753950.html 树转换为二叉树 (1)加线.在所有兄弟结点之间加一条连线. ( ...

  3. 数据结构——树、森林、二叉树的转换

    树.森林与二叉树的转换 树转换二叉树 规则:左孩子右兄弟,每个结点左指针指向它的第一个孩子结点,右指针指向它在树中相邻兄弟结点. 二叉树转换为树 规则: 逆过程,将指针修改回来,指向其双亲结点. 森林 ...

  4. [数据结构]树、森林与二叉树之间的相互转换方法

    树.二叉树与森林的相互转换 本文只给出树.森林与二叉树之间的转换方法,而详细的证明过程不在本文讨论范围之内. 树 → 二叉树 在所有兄弟结点之间加一连线. 对每个结点,除了保留与其长子的连线外,去掉该 ...

  5. 数据结构——树、二叉树、森林、哈夫曼树、字符串模式匹配

    %%%%%% 字符串模式匹配算法--详解KMP算法 https://blog.csdn.net/zc474235918/article/details/40474525 http://www.ruan ...

  6. 数据结构-树和二叉树01(定义、度、深度、有序树、森林)

    树的定义 树作为一种一对多的数据结构,其定义如下: 树(Tree)是n(n ≥ 0)个结点得有限集.n = 0时称为空树.在任何一颗非空树中: (1)有且仅有一个特定的称为根(Root)的结点: (2 ...

  7. 【数据结构-树】1.树与森林(树的遍历、树的存储方法、并查集的实现)

    树的定义 树是一种数据结构,它是由 n(n>=1)n(n>=1)n(n>=1) 个有限结点组成一个具有层次关系的集合.把它叫做 "树" 是因为它看起来像一棵倒挂的 ...

  8. 数据结构(十九) -- C语言版 -- 树 - 树、森林、二叉树的江湖爱恨情仇、相互转换

    内容预览 零.读前说明 一.树转换为二叉树 二.二叉树转换为树 三.二叉树转换为森林 四.森林转换为二叉树 五.树与森林的遍历 5.1.树的遍历 5.2.森林的遍历 零.读前说明 本文中所有设计的代码 ...

  9. 《数据结构与算法》(十一)- 树、森林与二叉树的转换及哈夫曼树详解

    目录 前言 1. 树.森林与二叉树之间的转换 1.1 树转换为二叉树 1.2. 森林转换为二叉树 1.3. 二叉树转换为树 1.4 二叉树转换为森林 1.5 树与森林的遍历 2. 哈夫曼树及其应用 2 ...

最新文章

  1. System.Configuration.ConfigurationSettings.GetConfig(string)”已过时 问题的解决方法
  2. struts2标签处理下拉列表
  3. 前端学习(1247):购物车1
  4. html调用app store,iOS 获取appStore的链接地址,从app中跳转 appStore中应用
  5. openssl 对文本加密解密
  6. SAP License:CO-FI实时集成
  7. 图(一):图的邻接表表示
  8. [摘]研究方法 - 实证研究
  9. Java--获取xml头encoding编码方式
  10. AcWing 188 武士风度的牛 题解(BFS)
  11. PageHelper.startPage和new PageInfo(list)的一些探索和思考
  12. 【应用宝】腾讯应用宝 上线APP为什么上线了 无法在应用宝搜索到(解决方法)
  13. 通过Excel VBA对序列实现自动分级
  14. 如何判断Map中的key或value是什么类型
  15. 你什么时候放下,什么时候就没有烦恼。
  16. JCD 驱动 - 复杂系统设计应对之道
  17. 瑞吉外卖笔记——第03讲Linux软件安装jdk、MySQL、Tomcat和Maven
  18. Fast-DDS库的安装教程
  19. EventBus如何使用及一些常见场景
  20. 计算机鼠标说课,可爱的鼠标说课稿(赵丽丽)

热门文章

  1. 计算机磁盘怎么加密码,电脑磁盘怎么设置密码
  2. Python毕业设计 大数据招聘网站爬取与数据分析可视化 - flask
  3. java kvm_KVM 介绍(1):简介及安装
  4. 119.【Uniapp】
  5. opencv 轻松入门 面向python pdf_OpenCV轻松入门:面向Python
  6. 【BZOJ1997】【HNOI2010】Planar(2-SAT,平面图,并查集)
  7. Elasticsearch的cpu使用率达到100%的原因以及解决方案
  8. 安全可信,用友U8 cloud荣获2022“信创云ERP”最具竞争力产品奖
  9. 计算机辅助系统应用于肺部,计算机辅助诊断技术在肺结节中的应用
  10. 抖音火爆的早安推送在线版,常见问题处理