数据结构~树和二叉树(三)

本人学习笔记,仅供自己查阅


树型结构是一类重要的非线性数据结构,其中以 数和二叉树 最为常用。

在任意一颗非空树中:

1)有且仅有一个特定的根结点;

2)当n>1时,其余结点可分为m个互不相交的子树。


二叉树 是另一种树型结构,它的特点是每个结点至多只要两棵子树(即二叉树不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。

二叉树的性质:

……

满二叉树:

完全二叉树:

二叉树链式存储结构:数据域和左、右指针域


 遍历二叉树:如何按某条搜索路径巡防树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。

遍历对线性结构来说,是一个很容易解决的问题。而对二叉树则不然,由于二叉树是一种非线性结构,每个结点都可能有两棵子树,因而需要寻找一种规律,以便使二叉树上的结点能排列在一个线性队列上,从而便于遍历。

假如以L、D、R分别表示遍历左子树、访问根结点和遍历右子树,且限定先左后右,有三种情况:DLR、LDR、LRD,分别称之为先(根)序遍历、中(根)序遍历和后(根)序遍历。

算法实现,暂无

遍历二叉树的算法中的基本操作是访问结点,则不论按哪一种次序进行遍历,对含n个结点的二叉树,其时间复杂度为O(n)。所需辅助空间为遍历过程中栈的最大容量,即树的深度,最坏情况下为n,则空间复杂度也为O(n)。


 线索二叉树

当以二叉链表作为存储结构时,只能找到结点的左、右孩子信息,而不能直接得到结点在任一序列中前驱和后继信息,这种信息只有在遍历的动态过程中才能得到。

如何保存这种在遍历过程中得到的信息呢?一个最简单的办法是在每个结点上增加两个指针域fwd和bkwd,分别指示结点在依任一次序遍历时得到的前驱和后继信息。

以这种结点结构构成的二叉链表作为二叉树的存储结构,叫做 线索链表,其中指向结点前驱和后继的指针,叫做线索。加上线索的二叉树称之为线索二叉树


树的存储结构

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

  这种存储结构利用了每个结点(除根以外)只有唯一的双亲的性质,在这种表示法中,求结点的孩子时需要遍历整个结构。

2)孩子表示法:由于树中每个结点可能有多棵子树,则可用多重链表,即每个结点有多个指针域,其中每个指针指向一棵子树的根结点。

  与双亲表示法相反,孩子表示法便于那些涉及孩子的操作的实现,却不适用于parent操作。

3)孩子兄弟表示法:又称二叉树表示法,或二叉树链表表示法。即以二叉链表作树的存储结构。链表中结点的两个链域分别指向该结点的第一个孩子结点和下一个兄弟结点,分别命名为firstchild域和nextsibling域。

  利用这种存储结构便于实现各种树的操作。首先易于实现找结点孩子等的操作。当然,如果为每个结点增设一个parent域,则同样能方便实现parent操作。


 赫夫曼树及其应用

赫夫曼树(Huffman),又称最优树,是一类带权路径长度最短的树,有着广泛的应用。

从树中一个结点到另一个结点之间的分支构成这个结点之间的路径,路径上的分支数目称作路径长度树的路径长度是从树根到每一结点的路径长度之和。(完全二叉树就是这种路径长度最短的二叉树)

若将上述概念推广到一般情况,考虑带权的结点结点的带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积。树的带权路径长度为树中所有叶子结点的带权路径长度之和。通常记作WPL = Σ wklk

假设有n个权值,试构造一棵有n个叶子结点的二叉树,每个叶子结点带权为wi,则树的带权长度WPL最小的二叉树称做 最优二叉树 或 赫夫曼树。

赫夫曼编码

目前,进行快速远距离通信的主要手段是电报,即将需传送的文字转换成由二进制的字符组成的字符串。

在传送电文时,希望总长尽可能地短。如果对每个字符设计长度不等的编码,且让电文中出现次数较多的字符采用尽可能短的编码,则传送电文的总长便可减少。

若要设计长短不等的编码,则必须是任一个字符的编码都不是另一个字符的编码的前缀,这种编码称做 前缀编码。

可以利用二叉树来设计二进制的前缀编码。 从根结点到叶子结点的路径上分支字符组成的字符串作为该叶子结点字符的编码。(无图,若无法理解,自行百度)

由此可见,设计电文总长最短的二进制前缀编码为以n种字符出现的频率作权,设计一棵赫夫曼树的问题,由此得到的二进制前缀编码便称为赫夫曼编码


回溯法与树的遍历(八皇后问题,未了解)

原文地址:https://www.cnblogs.com/barbarian/p/8675991.html