树与二叉树——补充总结

总结

树的性质:

1. 树中的结点数等于所有结点的度数之和+1。

  • 树结点与度之间的关系:
  1. 总结点数= n 0 + n 1 + . . . + n m n_0+n_1+...+n_m n0+n1+...+nm
  2. 总分支数= 1 × n 1 + 2 × n 2 + . . . + m × n m ( 度 为 m 的 结 点 引 出 m 条 分 支 ) 1×n_1+2×n_2+...+m×n_m(度为m的结点引出m条分支) 1×n1+2×n2+...+m×nm(mm)
  3. 总结点数=总分支数+1
  • 例: 在一棵度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶结点个数是82。

  • n 0 = x , n 1 = 10 , n 2 = 1 , n 3 = 10 , n 4 = 20 n_0=x,n_1=10,n_2=1,n_3=10,n_4=20 n0=xn1=10n2=1n3=10n4=20
    总结点数=x+10+1+10+20=41+x,总分支数=1×10+2×1+3×10+4×20=122;
    总结点数=总分支数+1 → \rightarrow 41+x=122+1 → \rightarrow x=82。

  1. 度为m的树中第i层上至多有 m i − 1 m^{i-1} mi1个结点 ( i ≥ 1 ) (i≥1) (i1)(满m叉树的情况)
  • m m m叉树第一层只有一个根结点,第二层最多有 m m m个结点,第三层最多有 m 2 m^2 m2个结点,…,第 i i i层最多有 m i − 1 m^{i-1} mi1个结点。
    树与二叉树——补充总结_第1张图片
  1. 高度为 h h h m m m叉树至多有 m h − 1 m − 1 \frac{m^h-1}{m-1} m1mh1个结点,至少有h个结点。
  • 最多结点情况:高度为 h h h的满 m m m叉树;
    第一层:1个;第二层: m m m个;第三层: m 2 个 m^2个 m2;第 h h h层: m h − 1 m^{h-1} mh1个。总的结点数: 1 + m + m 2 + . . . + m h − 1 = 1 ( 1 − m h ) 1 − m = m h − 1 m − 1 1+m+m^2+...+m^{h-1}=\frac{1(1-m^h)}{1-m}=\frac{m^h-1}{m-1} 1+m+m2+...+mh1=1m1(1mh)=m1mh1
  • 最少结点情况:高度为 h h h,每个结点下面连一个结点。总的结点数为 h h h
    树与二叉树——补充总结_第2张图片
  1. 具有 n n n个结点的 m m m叉树的最小高度为 ⌈ l o g m n ( m − 1 ) + 1 ⌉ ⌈log_m^{n(m-1)+1}⌉ logmn(m1)+1
  • 满足高度最小,要使每层的结点数最多,即满m叉树的情况。
  • 高度为 h h h m m m叉树最多有 m h − 1 m − 1 \frac{m^h-1}{m-1} m1mh1个结点,高度为 h − 1 h-1 h1 m m m叉树最多有 m h − 1 − 1 m − 1 \frac{m^{h-1}-1}{m-1} m1mh11个结点。因此 m h − 1 m − 1 < n ≤ m h − 1 − 1 m − 1 \frac{m^h-1}{m-1}<n≤\frac{m^{h-1}-1}{m-1} m1mh1nm1mh11
  1. 高度为 h h h,度为 m ( m ≥ 2 ) m(m≥2) m(m2)的树至少有h+m-1个结点。
    树与二叉树——补充总结_第3张图片
    二叉树的性质:

  2. 非空二叉树中, n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1,其中 n 0 n_0 n0表示叶子结点数, n 1 n_1 n1表示度为2的结点数。

  3. 非空二叉树上第 k k k层上至多有 2 k − 1 2^{k-1} 2k1个结点 ( k ≥ 1 ) (k≥1) (k1)(满二叉树的情况)。 (参考:树的性质2)

  4. 高度为 h h h的二叉树至多有 2 h − 1 2^h-1 2h1个结点。 ( h ≥ 0 ) (h≥0) (h0)(满二叉树的情况),最少有 h h h个结点。 (参考:树的性质3)

  5. 具有 n n n ( n > 0 ) (n>0) (n>0)结点的二叉树的高度为 ⌈ l o g 2 n + 1 ⌉ ⌈log_2^{n+1}⌉ log2n+1 ⌊ l o g 2 n ⌋ + 1 ⌊log_2^n⌋+1 log2n+1。(参考:树的性质4)
    10.每个结点的度或者为0或者为2的二叉树称为正则二叉树,对于n个结点的正则二叉树,它的最大高度是: n + 1 2 \frac{n+1}{2} 2n+1

  • 最大高度的正则二叉树是这样的二叉树:第1层有一个结点,第2层~第h层均有2个结点,因此2(h-1)+1=n,即 h = n + 1 2 h=\frac{n+1}{2} h=2n+1
  1. n 、 m n、m nm为一棵二叉树上的两个结点,在中序遍历时, n n n m m m前的条件是: n n n m m m左方
  2. n 、 m n、m nm为一棵二叉树上的两个结点,在后序遍历时, n n n m m m前的条件是: n n n m m m子孙
  3. 若某非空二叉树的先序序列和后序序列正好相反,则该二叉树的形态是:其高度等于结点个数
    树与二叉树——补充总结_第4张图片
  4. 若某非空二叉树的先序序列和后序序列正好相同,则该二叉树的形态是:二叉树只有一个根结点
  5. 若某非空二叉树的先序序列和中序序列正好相反,则该二叉树的形态是:所有结点没有右子树的单支树

森林和二叉树:

设森林F转化为对应的二叉树为B
树与二叉树——补充总结_第5张图片

  1. 设F有3棵树,第一、第二、第三棵树的结点个数分别为 M 1 、 M 2 、 M 3 M_1、M_2、M_3 M1M2M3。则B根结点的右子树上的结点个数为: M 2 + M 3 M_2+M_3 M2+M3
  2. B有m个结点,B的根为p,p的右子树结点个数为n,F中第一棵树的结点个数为:m-n
  3. F中叶结点的个数等于B中左孩子指针为空的结点个数。
  4. 双亲存储结构表示树,其优点之一是比较方便找指定结点的双亲结点
  5. 若F中有m个分支结点,则B中右指针域为空的结点有m+1个。
  6. 孩子链存储结构表示树,其优点之一是计算指定结点的度数比较方便。
  7. 若用孩子兄弟链存储结构来存储具有 m m m个叶子结点, n n n个分支结点的树,则该存储结构中有 m m m个左指针域为空的结点,有 n + 1 n+1 n+1个右指针域为空的结点。
  8. 一棵度为10、结点个数为n(n>100)的树采用孩子链存储结构时,其中非空指针域数占总指针域数的比例约为:10%。
  • 一棵树的度为10,则采用孩子存储结构,每个结点的指针域个数为10,共有10n个指针域,其中非空的指针域个数等于分支数,即n-1,其余为空指针域,所以非空指针域数占总指针域数的比例= n − 1 10 n ≈ 10 % \frac{n-1}{10n}≈10\% 10nn110%
  1. 有一棵3次树,其中 n 3 = 2 , n 2 = 2 , n 1 = 1 n_3=2,n_2=2,n_1=1 n3=2,n2=2,n1=1,当该树采用孩子兄弟链存储结构时,其中非空指针域数占总指针域数的比例约为:45%。
  • n = 2 × 3 + 2 × 2 + 1 × 1 + 1 = 2 + 2 + 1 + n 0 → n 0 = 7 n=2×3+2×2+1×1+1=2+2+1+n_0 \rightarrow n_0=7 n=2×3+2×2+1×1+1=2+2+1+n0n0=7
    n = 12 , n 0 = 7 n=12,n_0=7 n=12n0=7。当采用孩子兄弟链存储结构时,每个结点有两个指针域,一个指向孩子,一个指向兄弟,总指针域个数为24。指向孩子或者兄弟的非空指针域个数=n-1=11,所以非空指针域数占总指针域数的比例= 11 24 ≈ 45 % \frac{11}{24}≈45\% 241145%

哈夫曼树:

1.若度为m的哈夫曼树(其中只有度为m的结点和叶子结点)中,其叶子结点个数为n,则非叶子结点的个数为:⌈ n − 1 m − 1 − 1 \frac{n-1}{m-1}-1 m1n11⌉。

  • 在度为m的哈夫曼树中,设度为m的结点个数为 n m n_m nm n = m × n m + 1 = n m + n → n m = ⌈ n − 1 m − 1 ⌉ n=m×n_m+1=n_m+n \rightarrow n_m=⌈\frac{n-1}{m-1}⌉ n=m×nm+1=nm+nnm=m1n1
  1. n个符号构成哈夫曼树,共新建了n-1个结点(双分支结点),因此哈夫曼树的结点总数为:2n-1

度为m的树 VS m叉树

度为m的树 m叉树
树的度:各结点的度的最大值 m叉树:每个结点最多只能有m个孩子的树
至少有一个结点的度等于m 允许所有结点的度都小于m
一定是非空树,至少有m+1个结点 可以是空树
任意结点的度≤m

设二叉树的存储结构为二叉链表,有关二叉树的递归算法

  • 二叉树的递归算法主要基于先序/中序/后序遍历的递归代码,根据不同算法要完成的功能做相应的实现,原始的三种递归算法如下:
void PreOrder(BiTNode* t) //先序遍历
{
    if (t != NULL) //不是空树时遍历
    {
        printf("%c ", t->data); //访问根节点
        PreOrder(t->lchild); //先序遍历左子树
        PreOrder(t->rchild); //先序遍历右子树
    }
}

void InOrder(BiTNode* t) //中序遍历
{
    if (t != NULL)
    {
        InOrder(t->lchild);
        printf("%c ", t->data);
        InOrder(t->rchild);
    }
}

void PostOrder(BiTNode* t) //后序遍历
{
    if (t != NULL)
    {
        PostOrder(t->lchild);
        PostOrder(t->rchild);
        printf("%c ", t->data);
    }
}
  • 统计二叉树中度为0 / 度为1 / 度为2的结点个数
  • 点击 !参见第四题
  • 统计二叉树的高度/宽度
  • 求二叉树高度三种方法:①后序遍历非递归 ②层序遍历非递归 ③递归
    点击 !参见第九题
  • 求二叉树宽度:层次遍历非递归算法 点击 !参见最后一题
  • 从二叉树中删去所有叶结点
void Delete_Leaf(BiTNode* t)
{
    if (t != NULL)
    {
        if (t->lchild != NULL) //左子树中的叶子结点
            if (t->lchild->lchild == NULL && t->lchild->rchild == NULL)
            {
                free(t->lchild);
                t->lchild = NULL;
            }
        if (t->rchild != NULL) //右子树中的叶子结点
            if (t->rchild->lchild == NULL && t->rchild->rchild == NULL)
            {
                free(t->rchild);
                t->rchild = NULL;
            }
        Delete_leaf(t->lchild); //递归删除左子树中的叶结点
        Delete_leaf(t->rchild); //递归删除右子树中的叶结点
    }
}

运行结果:树与二叉树——补充总结_第6张图片

  • 计算指定结点*p所在的层次
int GetLevel(BiTree T, BiTNode *p) //计算指定结点*p所在的层次
{
	if (T == NULL) return 0; //空树
	if (T == p) return 1; //指定结点为根节点
	int depl = GetLevel(T->lchild, p); //递归在左子树中查找
	int depr = GetLevel(T->rchild, p); //递归在右子树中查找
	if (depl || depr)  return (depl > depr) ? 1 + depl : 1 + depr; 
	//使用三目运算符返回左、右子树中深度大的值,加上根节点的高度1
	return 0; //不存在指定结点*p
}

运行结果:
树与二叉树——补充总结_第7张图片

  • 计算二叉树中各结点中的最大 / 最小元素的值
  • 点击!参见第十六题
  • 交换二叉树中每个结点的两个子女(左、右子树交换)
  • 点击 !参见第五题
  • 以先序/中序/后序次序输出一颗二叉树中所有结点的数据值及结点所在的层次
  • 以先序递归为例,中序和后序只需要调整递归的三行代码的顺序即可:
void NodeAndLevel(BiTNode* t, int i) //以先序序列输出一棵二叉树中的所有结点的数据值及结点所在层次
{//第一次调用为PreAndLevel(T, 1);
    if (t != NULL)
    {
        printf("data=%c,level=%d\n", t->data, i);
        PreAndLevel(t->lchild, i + 1);
        PreAndLevel(t->rchild, i + 1);
    }
}

运行结果:
树与二叉树——补充总结_第8张图片

  • 二叉树的非递归算法主要有:先序/中序/后序/层序的非递归算法,其中层序遍历使用比较广泛,它需要借助队列来实现,在层序算法中可以标记每一个结点的序号,如下图,这种方法同样可以解决二叉树中的许多问题。
    树与二叉树——补充总结_第9张图片
  • 统计二叉树的高度/宽度
  • 某i的结点个数 / 每层的结点个数 / 第i层中的第j个结点
  • 点击!参考最后两题非递归算法的实现

你可能感兴趣的:(计算机技术,数据结构,树与二叉树,哈夫曼树)