zoukankan      html  css  js  c++  java
  • 树(一)树的基本知识

    树结构

    1) 了解树的定义、表示形式和基本术语

    2) 了解二叉树的概念和性质

    3) 掌握二叉树的几种遍历方法

    4) 理解二叉树的遍历方法的C语言代码实现

    5) 了解树的存储结构

    6)了解哈夫曼树和哈夫曼编码的基本概念

    树的定义

    (Tree),是n(n≥0)个结点的有限集。若n=0时称为空树;若n>0时为非空树。

    在一个非空树中,有且仅有一个称为的结点。除根以外的其他结点划分为m(m>0)个互不相交的有限集T1,T2,. . .,Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。

    例如下图是只有一个结点的树,这个唯一的结点也是这棵树的根节点:

     

                

     

    再比如下面这棵树:

          

     

    这棵树有9个结点,其中A是根,其余结点组成2个互不相交的子集:T1={B, D, E, I},T2={C, F, G, H},T1和T2都是A的子树,其本身也是一棵树:

     

    在树T1中,B是根节点,其余结点又分为两个互不相交的子树:T11={D, I},T12={E}。在树T11中D是根,其包含由结点I组成的子树。从这个概念上我们可以看出树的定义是一个递归的定义,即在树的定义中又用到了树的定义,而递归也将是实现树的相关操作的一个重要手段。

    树的表示方法

    树形表示法

    目录结构表示

    韦恩图表示法

        

    广义表表示法

    凹入表示法

    树的基本概念(※有关术语※重点※

    以下图为例子:

    • 结点:数据元素以及指向子树的分支。图中的A,B,C等都是结点。

    • 根结点:非空树中无前驱结点的结点。图中的A结点。

    • 结点的度(Degree):结点拥有的子树数量。图中度为3的有:A、D,度为2的有:B、E、H,度为1的有:C、H。

    • 树的度:树内各结点的度的最大值。上图中树的度为3。

    • 叶子结点(终端结点)(Leaf):树没有子结点,即度为0的结点。图中的F,G,I,J,K,L,M 都是叶子结点。

    • 分支结点(分支点或非终端结点):不属于叶子结点的结点,即度不为0的结点。A,B,C,D等都是分支结点。

    • 内部结点(中间结点):根结点以外的分支结点。B,C,D,E,H等都是内部结点。

    • 层次(Level):从根结点开始,根结点为第一层(A),根的子结点为第二层(B,C,D),以此类推。从根结点到树中某结点所经路径上的分支数称为该结点的层次根结点的层次在不同教材中有规定为1,也有规定为0,其余结点的层次等于其双亲结点的层次加1。所以某结点在第n层,则其孩子就在第n+1层。(笔者这里默认根结点为1)

    • 结点深度:对任意结点x,x结点的深度表示为根结点到x结点的路径长度。所以根结点深度为0,第二层结点深度为1,以此类推;如深度为3的结点有:K,L,M,深度为2的结点有:E、F、G、H、I、J

    • 结点高度:对任意节点x,叶子节点到x节点的路径长度就是节点x的高度

    • 树的深度:树从根结点开始往下数,叶子结点所在的最大层数称为 树的深度。一棵树中结点的最大层次就是树的深度,深度定义是从上往下的。如图中树的深度为:4(默认根结点为1)

    • 树的高度:数值上和深度一样,高度定义是从下往上的。如图中树的高度为:4

    • 孩子-双亲(child-parent):结点的子树的根称为该结点的孩子,该结点称为孩子的双亲。图中,E是L的双亲,L是E的孩子。

    • 兄弟结点(Sibling):有一些结点,它们有共同的双亲,则称这些结点为兄弟结点。图中的H,I,J就是兄弟结点。

    • 堂兄弟结点:双亲在同一层上的结点称为堂兄弟结点。图中的G,H就是堂兄弟结点。

    • 结点的祖先:从根到该结点所经分支上的所有的结点。A,D,H结点都是结点M的祖先。

    • 结点的子孙:以某结点为根的子树中的任一结点。

    • 树的深度:树中结点的最大层次。图中的树的深度为4。

    • 有序树:树中结点的各子树从左至右右次序。

    • 无序树:树中结点的各子树无次序。

    • 森林:是m(m≥0)棵互不相交的树的集合。把根结点删除树就变成了森林;一棵树可以看成是一个特殊的森林;给森林中的各子树加上一个双亲结点,森林就变成了树。

    树一定是森林,而森林不一定是树。

     

    二叉树(Binary Tree)

    二叉树的定义

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

    P.S. 殷人昆教授对于二叉树的基本定义——

    二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。

    二叉树的特点

    1)二叉树每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点

    2)左子树和右子树是有顺序的,次序不能任意颠倒

    3)即使树中某个结点只有一棵子树,也要严格区分左右。

    为什么要重点研究最多只有两个“叉”的树呢?因为二叉树的结构最简单,规律性最强,另外还可以证明所有的树都可以转为唯一对应的二叉树。

    二叉树的基本形态

    二叉树有五种基本形态:

    1)空二叉树

    2)只有一个根结点

    3)根结点只有左子树

    4)根结点只有右子树

    5)根结点既有左子树又有右子树

    如下图所示:

    从基本形态延申形态

    从这五种基本形态考虑,如果一棵树只有三个结点,那么这棵二叉树可以有如下几种形态,而且它们代表了不同的二叉树:

     

    特殊二叉树

    斜树

    该二叉树中的所有结点只有左子树或者只有右子树,相对应的就被称为左斜树和右斜树。如下图所示:

     

    满二叉树(Full Binary Tree)

    在一棵二叉树中,如果所有的分支结点都存在左子树和右子树,并且叶结点都在同一层上,这样的二叉树就称为满二叉树。例如下图所示:

     

    满二叉树的定义:

    一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。

    深度k的满二叉树是有2^k-1个结点的二叉树,在满二叉树中,每一层结点都达到了最大个数,除最底层结点的度为0外,其他各层结点的度都为2。

    满二叉树的特点

    a.叶子只能出现在最下一层

    b.非叶子结点的度一定是2

    c.同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。

    完全二叉树(Complete Binary Tree)

    如果对一棵具有n个结点的二叉树按层序编号,如果该树中结点的编号与同样深度的满二叉树中相同位置的结点的编号完全相同时,称之为完全二叉树。如下图所示:

    满二叉树一定是完全二叉树,但完全二叉树不一定是满的。

    如果因为某些结点缺少子树导致空挡,而使得编号不对应时,就不能算是完全二叉树,如下图的树就不是一棵完全二叉树:

    完全二叉树的定义

    如果一棵具有n个结点的深度为k的二叉树,它的每一个结点都与高度为k的满二叉树中编号为1 ~ n-1的结点一一对应,则称这棵二叉树为完全二叉树。 其特点是:上面从第1层到第k-1层的所有各层的结点数都是满的,仅最下面的第k层是满的,或从右往左连续缺少若干结点。

    完全二叉树的特点

    a.叶子结点只能出现在最下两层。

    b.最下层的叶子一定集中在左部连续位置。

    c.倒数第二层如果有叶结点,一定都在右部连续。

    d.如果结点度为1,则该结点只有左孩子,不存在只有右子树的情况。

    e.相同结点树的二叉树中,完全二叉树的深度最小。

    二叉树的性质(※重点※)

    参考https://www.cnblogs.com/duan-decode/p/9610986.html

    接下来的描述中有必要用到一些数学符号,在Markdown中不好画出,因此我们再次规定一些符号——

    • a^b—— a的b的次方 (计算机常用,无需多言)

    • int_UP()—— 向上取整(即去掉浮点数的小数部分,然后将整数部分加1)

    • int_DOWN()—— 向下取整(即去掉浮点数的小数部分,只留整数部分)

    • log(a,b) —— 表示以a为底取b的对数

    以下图为例

                图1

                图2

    性质1:

    在二叉树的第i(i>=1)层 1最多有2^(i - 1)个结点。 (默认根结点为第一层)

    证明:通过数学归纳法----因为说的是第i层的最多的结点数,所以可以观察满二叉树,第1层有1个跟结点A,第2层有2个跟的子结点(B,C),第3层有4个结点(D,E,F,G),第四层有8个结点,可以发现第2层开始每一层都是上一层的2倍,很容易归纳出第i层最多有2^(i - 1)个结点。

    性质2:

    深度 2为k(k>=0)的二叉树最少有k个结点,最多有2^k-1个结点 (默认根结点为1)

    由性质1可知,k层的最大节点总数可表示为2^0+2^ 1+……+2^ (k-1) = 2^k- 1;

    注意这里不是2的(k-1)次方,而是2的k次方再减1。同样以满二叉树来观察,深度即层数,1层的满二叉树只有1个结点,2层时有(1+2)个结点,3层时有(1+2+4)个结点,这里使用简单的数学知识可做以下推导,记深度为k的二叉树最多结点数为Sk,则有:

    Sk=2^0+2^1+2^2+…+2^(k-1) 对该式两边乘以2可得:

    2Sk=2^1+2^2+2^3+…+2^k 再使用下式减去上式可得:

    Sk=2^k-2^0,所以可得深度为k的二叉树最多有2^k - 1个结点(满二叉树),最少为k个结点(只有左子树或右子树)。

    性质3:

    对于任一棵非空二叉树,若其叶子结点(度 3为0的结点)数为n0,度为2的非叶子结点(分支结点)数为n2,则n0=n2+1;

    证明:设,度为2的结点数为n2,且有两条通向子结点的边,度为1的结点数为n1,且有一条边,度为0的结点数为n0,无边。

    计算结点总数:

    二叉树的度只可能为0(只有一个·根结点或叶子结点)或1或2;

    所以树中结点总数为 N = n0 + n1 + n2;①

    计算树的边数:

    边的总数为 E = n2 * 2 + n1 * 1 + n0 * 0;②

    根据定义:树中,边的条数 = 结点总数 - 1,因此得到:

    E = N - 1;③

    联立 ① ②③ 消去E、N,可得:n2 * 2 + n1 = n0 + n1 + n2 -1 ;

    即 n0 = n2 + 1;

    性质4:

    具有n个结点的完全二叉树的深度为int_UP(log(2,n+1))。(int_UP :向上取整)

    3.321928向上取整为 4,因此 树的深度为4;

     

    性质5:

    如果将一棵有n个结点的完全二叉树自顶向下,同一层自左向右连续给结点编号1,2,3,......,n,然后按此结点编号将树中各结点顺序的存放于一个一维数组,并简称编号为i的结点为结点i( i>=1 && i<=n),则有以下关系:

    1. 若 i= 1,则结点i为根,无父结点;若 i> 1,则结点 i 的父结点为结点int_DOWN(i / 2);

    2. 若 2*i <= n,则结点 i 的左子女为结点 2*i; (根结点为1时,左结点为偶数)

    3. 若2*i<=n,则结点i的右子女为结点2*i+1; (根结点为1时,右结点为奇数)

    4. 若结点编号i为奇数,且i!=1,它处于右兄弟位置,则它的左兄弟为结点i-1;

    5. 若结点编号i为偶数,且i!=n,它处于左兄弟位置,则它的右兄弟为结点i+1;

    6. 结点i所在的层次为 int_UP(log(2,i+1))。 (如图2中 8 在第四层,对log(2,9)向上取整为4 )

    [ 1]  根结点的层次在不同教材中有规定为1,也有规定为0,其余结点的层次等于其双亲结点的层次加1。所以某结点在第n层,则其孩子就在第n+1层。(笔者这里默认根结点为1)
    [ 2]  树从根结点开始往下数,叶子结点所在的最大层数称为 树的深度。一棵树中结点的最大层次就是树的深度,
    [ 3]  结点的度(Degree):结点拥有的子树数量。)

     《未完待续------》

  • 相关阅读:
    Repeater 双向排序
    将具有固定格式的text 类型中的数据分离出来的一种方法
    ASP.NET 快速构建应用程序页面主框架
    2分分页处理存储过程通用存储过程
    C#3.0之匿名类型
    常用的js收集
    用CSS实现DataGird滚动而表头不动
    Lucene.Net 创建索引和检索
    Lucene.net 实现全文搜索
    SQL 中操作日期的几个函数
  • 原文地址:https://www.cnblogs.com/destiny-2015/p/13778066.html
Copyright © 2011-2022 走看看