• 数据结构之树


    第一部分:定义

      树(Tree)是n(n>=0)个结点的有限集。 n = 0 时成为空树。在任意一颗非空树中: 

        (1). 有且仅有一个特定的成为根(root)的节点。

        (2). 当 n > 1 时,其余结点可以分为m个互不相交的有限集 T1、 T2、 T3 .....Tm,其中每一个集本身又是一棵树,并且称为根的子树

      

    第二部分:基本概念

      1. 结点分类

       在一棵树中,结点分为 根结点内部结点叶结点(又称终端结点)。

      结点拥有的子树的数目称为结点的度(Degree)。 B的度为1, D的度为3

      在一棵树中, 最大的结点的度为树的度。  由于D的度最多,所以树的度就是3.

      

      

       2.节点间关系

         其中B是A的孩子A是B的双亲, C是B的兄弟。 之所以称之为双亲是因为对于结点来说父母同体,只有这么称呼是比较合适的了。

      

        3. 其他相关概念

         结点的层次: 从根开始算起, 根为第一层,然后第二层,第三层....

          树的深度或高度: 结点的最大层次就是树的深度或高度。

          有序树:如果将树中结点的各子树看成是从左到右有次序的,不能互换的,那么该树就是有序树,否则就是无序树

    第三部分: 树的存储结构

       我们知道, 树中某个结点的孩子有多个,所以无论是使用顺序存储结构还是使用链式存储结构,都不能很好的表示树。但是我们可以利用顺序存储结构和链式犓结构的特点来实现之。

       一. 双亲表示法

       我们假设以一组连续的空间存储树的结构,同时在每个节点中,附加一个指示器指示其双亲结点在数组中的位置,也就是说,每个结点不仅仅知道自己是谁意外,还知道它的双亲在数组中的哪个位置。  

       即一个结点包含两个部分: 1.  data(数据域) --- 用于存储结点的数据信息。   2. parent (指针域) --- 用于存储该结点的双亲在数组中的下标

        

       注意: 这样的好处是我们可以根据结点的parent指针很容易的找出它的双亲结点,所以复杂度是O(1),  但是如果我们要知道结点的孩子是谁,就得遍历整个结构才行。为了解决这个问题,我们可以增加一个结点最左边孩子的域,可以称之为长子域。  孩子可以找到了, 但是找兄弟呢 ? 我们还可以增加一个兄弟域,这样,可以发现:

    存储结构的设计是一个非常灵活的过程,一个存储结构设计的是否合理,取决于该存储结构的运算是否合适、是否方便, 时间复杂度好不好等等。  

      

       二. 孩子表示法

        如果一棵树中的每一个结点都有很多的孩子,  那么这时孩子为重,  我们就可以考虑每个结点有多个指针域, 每个指针域指向一颗子树的根节点, 这种方法就是多重链表表示法。 不难想象,多重链表表示法的最终结构和一颗树的结构是无异的。但是根据一个结点需要多少个域的不同,我们可以将多重链表表示法分为下面两种:

       1. 每个结点的指针域的个数是数的度

         优点 这样做的好处在于树的结构是稳定的、整齐的、维护起来较为方便。 缺点 坏处在于有可能很多指针域都是空着的,造成了资源的浪费。

       2. 每个结点的指针域的个数就是其子节点的个数(即它的度)

          优点  这样做的好处在于不会造成资源的浪费。  缺点 坏处在于这样在后期维护起来会比较麻烦,且结构会比较混乱。

       ok!  那有没有一种方法可以回避上面的缺点呢? 当然有,这就是孩子表示法了, 孩子表示法,即以n个结点的单链表作为存储结构, 则n个结点就有n个孩子链表,每个结点又会引出孩子的节点(如果没有孩子,就不会引出,如果有,就一直引下去)。

        这样的表示法缺点在于,如果知道某个结点的双亲是谁呢?  并不难,只要我们把双亲表示法和孩子表示法综合一下不就行了吗?  这种思路当然可行

       三、 孩子兄弟表示法

      

    第四部分:二叉树

      二叉树(Binary Tree)是n个结点的有限集合,该集合或者为空集,或者由一个根节点和两颗互不相交的、分别称为根节点的左子树和右子树的二叉树组成。  

      1. 二叉树的特点

    1.  每个结点最多有两个子树。
    2.  左子树和右子树的顺组是不能随意颠倒的。
    3.  即使某个结点只有一个子树,也要分清楚左子树还是右子树。
    4. 三个结点可以构成 5 种不同的二叉树

      

      2. 一些特殊的二叉树

    1. 斜树  如上图中的第二个图和最后一个图就是斜树 ---  每一层都只有一个结点,结点的个数和二叉树的深度相同。
    2. 满二叉树 在一颗二叉树中,如果所有分支结点都存在左子树和右子树,并且所有的叶子都在同一层上, 这样的二叉树就称为满二叉树
    3. 完全二叉树  对于一颗具有n个结点的二叉树按层序编号,如果编号为i (1 <= i <= n)的结点与同样深度的满二叉树中编号为i的结点在树中的位置完全相同,则这棵树就是完全二叉树。  编号方式: 从上到下,从左到右。
    4. 注意: 满二叉树一定是完全二叉树, 完全二叉树不一定是满二叉树。

      

      3. 二叉树的5条性质

      性质一:  在二叉树的第i层上最多有2i-1  个结点。(i>=1).   如二叉树的第三层上最多有2 的 2 次方个结点。

      性质二: 在深度(或高度)为k的二叉树上最多有 2k - 1 个结点。  如深度为3的二叉树的结点数最多为 2 - 1 = 7个结点。

      性质三: 对于任意一颗二叉树T, 如果其终端的节点数为n ,度为2的节点数为n2, 则有n0= n+ 1; 

      性质四: 具有n个结点的完全二叉树深度为[log2n] + 1 (其中[x]表示不大于x的最大整数)。

      性质五: 

      如果对一颗有n个结点的完全二叉树(其深度为[log2n] + 1)的结点按层序编号(从上到下,从左到右), 对任一结点i (1 <= i <= n)都有:

        1. 如果 i = 1, 那么结点i是二叉树的根。 如果i > 1, 那么双亲是结点[i/2]。

        2. 如果 2i>n, 则结点 i 无左孩子,否则其做孩子是2i。

        3. 如果2i + 1 > n, 则结点i无右孩子, 否则其右孩子是结点 2i + 1;

      

    第五部分:遍历二叉树

    二叉树的遍历 ( traversing binary tree )是指从根节点出发, 按照某种次序依次访问二叉树中的所有结点,使得每个结点都被访问一次且仅被访问一次。  

      这里的两个关键词是 访问 和 次序。

      显然,二叉树的访问次序不同于线性结构,对于线性结构而言,最多也就是从头到尾、循环、双向等简单的遍历方式。树的结点之间不存在唯一的前驱和后继,所以在访问了一个结点之后,下一个被访问的结点面临着不同的选择。因而,对于二叉树而言,遍历结点的方式就完全不同了。

      说明:一般我们的习惯是从左到右的,这里同样也做出这样的限制。那么遍历时,前中后是指根节点被访问的时间上的前、中、后。 

      如前序遍历时先访问根节点、 中序历时中间的时候访问根节点、后续遍历是最后访问根节点。 不论是哪种遍历方式都是先左子树、后右子树。

    一: 前序遍历

      规则: 若二叉树为空, 则空操作返回,否则先访问根结点,然后前序遍历左子树,在前序遍历右子树。

       在二叉树中,先根后左再右。巧记:根左右。

    二: 中序遍历

      规则: 若树为空, 则空操作返回, 否则先从根节点开始(注意并不是先访问根节点),中序遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树。

         在二叉树中,先左后根再右。巧记:左根右。

      注意: 对称遍历就是中序遍历。

    三: 后续遍历

      规则: 若树为空,则空操作返回,否则从左到右先叶子结点的方式遍历访问左子树,最后是访问根节点。

      在二叉树中,先左后右再根。巧记:左右根。

    四:层序遍历

      规则: 若树为空,则空操作返回,否则从树的第一层开始,也就是根节点开始访问,从上而下逐层遍历,在同一层中,按照从左到右的顺序对结点逐个访问。

      这个是最为简单的,只要遵循从上到下、从左到右的规则即可。

    规则: 1. 这里的空操作返回,就是指向上返回,且空操作返回是共同点。   2. 这里的左子树、右子树和根节点都是相对的,环境和事件稍有改变,这些名词所代表的实体就发生了彻底的变化。

       3. 每次访问到一个节点,那么就要以这个节点作为根节点看作一个二叉树。

  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6533381.html
Copyright © 2020-2023  润新知