树以及二叉树的常用性质以及遍历

在这里插入图片描述

一个节点有几个度,就是看这个节点有几个分支,如A节点的度为2,B节点的度为1,而D节点的度为3.

  • 树的度

树的度为这个树所有有最大的度的那个节点的度,例如在上图中,树的度为3(取决于D节点的度)。

  • 叶子节点与非叶子节点

度为0的节点为叶子节点,度非0的节点为非叶子节点,如G,H,I是叶子节点.而C,D,E不是叶子节点。

  • 父节点

一个子节点上级节点,在一个树中,除了根节点以外,其他节点都有唯一的一个父节点

  • 祖先节点
    依次递归所有父节点,例如,节点H的祖先节点有DBA,E的祖先节点有CA

  • 后代节点

依次递归所有度节点,例如C的后代节点有EFJ,E的后代节点有J。

  • 兄弟节点

有共同父节点的节点之前成为兄弟节点,例如B,C,E与F互为兄弟节点

  • 堂兄弟节点

处于同一级的节点为堂兄弟节点,D,E,F互为堂兄弟节点。

  • 树的高度

就是表示树的层级,一共有几层,上图树共有4层。

  • 区分 度为m的树与m叉树

度为m的树表示该树至少存在一个节点,且有m个分支,而m叉树表示每个节点的度小于等于m。设m等于3,则度为3的树至少有4个节点,而3叉树可以有0个节点,也可以有任意多个节点,但是每个节点的度不能超过3,可以等于3.

树的性质
  • 树的总节点数等于树的总度数+1

总度数就是所有节点的度数相加

  • 度为m的树,第i层最多有m (i-1) 个节点
    度为5的树,第3层最多有 52个节点。
    就是说如果度为5,第二层最多有5个节点,
    第二层的每个节点最多又可以有5个节点,所有第三层就是 5*5 = 25个节点。

  • 高度为h的m叉树最多有 mh-1/m-1个节点

高度为3的5叉树最多有 5*5 + 5 + 1 = 31个,带入公式计算一下 53 - 1 / 4 = 31 是一样的。

  • 高度为h的m叉树最少有h个节点

这个也比较好理解,因为是m叉树,所以允许每一次只有一个节点,则高度为h的m叉树如果每一层只有一个节点,那么至少就会有h个节点。

  • 高度为h,度为m的树最少有 (h + m) - 1 个节点

首先度为m的树最少有m+1个节点,没加一层就需要至少加一个节点,所以h层就需要加h个节点,减去根节点和与度为m层的那个节点 就是 (h+m + 1) - 2 = h + m - 1。例如高度为3,度为3的节点至少有 5个节点。
根节点,根节点下面可以有一个节点,这个节点下面需要有3个节点,此时满足了度为3,高度为3.

  • n个节点的m叉树最小高度应为 [logm(n*(m-1)+1)]。

15个节点的2叉树最小高度等于 [log2(15*(2-1)+1) ]= 4。

这个高度算出来的结果是需要向上取整的。

满二叉树性质
  • 只有叶子节点的度为0,其他节点的度为2也就是说在满二叉树中,节点的度要么是2,要么是0

  • 若按照层序从上到下,从左到右从1开始编号,则第i个节点的左子节点为2i,第i个节点的右子节点为2i+1,第i个节点的父节点为 [i/2],向下取整,例如,第三个节点的父节点是 3/2 向下取整等于 1。

完全二叉树性质
  • 如果一个二叉树不是满二叉树,则应该是除了最后一层不是满的之外,其他层必须都是满的
    也就是说不允许出现非末尾层不是满二叉树的情况,除此之外,最后一层的节点应该是从左往右排序,
    中间不能有间隔。

  • 在完全二叉树中,只有最后两层才可能会出现叶子节点

  • 最多只有一个度为1的节点

  • 计算一个完全二叉树中的父节点位置以及子节点位置可用满二叉树的性质

  • 若一个含有n个节点的完全二叉树,则小于 等于[n/2]的节点为分支节点,大于 n/2的节点为叶子节点。

13个节点,13/2 再向下取整是6,也就是说前6个节点是分支节点,后7个节点是分支节点。

二叉排序树
  • 左子树所有子节点小于根据点,右子树所有子节点大于根节点
平衡二叉树
  • 任何一个子树的高度差不能超过1,也就是红黑树,此算法为了避免一个树的过于窄高,使得树尽量变得宽矮,能在log2n的时间复杂度内查询出来。

注意:二叉树和满二叉树还有完全二叉树不是一回事,满二叉树与完全二叉树是两种特殊的二叉树,二叉树的度允许为0,1,2,而满二叉树的度允许为0,2,完全二叉树的度允许为0,1,2,但最多只能存在1个度为1的节点

二叉树CK性质
  • 度为0的点比度为2的点多一个(n0 = n2+1)。

设一个二叉树的总节点树为n个,度为0的节点数为n0个,度为1的节点数为n1个,度为2的节点数为n2个,则

  1. n = n0 + n1 + n2
  2. n = n1 + 2n2 + 1

第二个公式的推算过程:二叉树的总节点个数为总度数+1,(除了根节点,其余每个节点都有一个父节点)。

那么在第二个公式中, n1+2n2 就是表示的总度数?为何?因为度为1的节点贡献了1个度,度为2的节点贡献了2个度,所以度为2的节点的度要乘2. 最后再加上1,表示了总节点数。

那么用2式-1式得出 (n0 = n2+1)。

  • 高度为h的满二叉树 一共有 22-1个节点

  • 高度为h的满二叉树第i层有 2i-1 个节点

完全二叉树CK性质
  • 具有n个节点的的完全二叉树的高度为 上取整[log2(n+1)],

或 下取整 ( [log2n] + 1 ) 。
例如 16个节点的完全二叉树的高度等于 [log217],向上取整就是 5.

  • 知道完全二叉树的节点个数,可求出n0,n1,n2

n1就是度为1的数,那在一颗满二叉树中,最多存在0个或1个度为1的节点,所以n1 = 0 或 n1 = 1,根据二叉树的性质得 n0 = n2 + 1.

n0 + n2 = (n2 + n2 + 1) = 2n2 + 1(必为奇数,叶子节点与双分支节点得数量总和,必为奇数),可得出结论

  1. 如果一个完全二叉树有偶数个节点 , 由于 n0 + n2 必为奇数,所以n1等于1,有一个度为1的节点。若n0为k,则n2为k-1.
  2. 如果一个完全二叉树有奇数个节点,由于n0+n2必为偶数,所以n1等于0,有0个度为1的节点,若n0为k,则n2为k-1.
顺序存储的方式实现二叉树

这里为了能够按照之前的给每个节点的编号,所以二叉树需要为满二叉树或者完全二叉树。

第i个节点的左子节点为2i
第i个节点的右子节点为2i+1
第i个节点的父节点为 i/2 向下取整
第i个节点是否为叶子节点 i > n / 2

链式存储方式实现二叉树

通常地,如果用里链式存储实现二叉树的话,那么结构中需要包含两个指针,一个是左子节点的指针,一个是右子节点的指针。所以可得出结论。一个节点为n的二叉树,共有2n个指针(因为一个节点有2个指针,所有共有2n个指针),非空指针n-1个(非空指针就是根节点的左右节点指向不为null的节点,那么现在假设,二叉树有n个节点,此时除了根节点以外,其他任意一个节点必定有一个指向他的指针,所以一共有n-1个有效指针),那么无效指针自然就有n+1个(也就是指向null的指针)。

二叉树的遍历方式

二叉树的遍历主要有4种遍历方式
1.中序遍历(中根遍历,左根右遍历):
先遍历左节点,再遍历根节点,再遍历右节点,也就是说对于每一个树和每一个子树来说,根节点一定是在左节点和后面,同时一定在左节点的前面
2.前序遍历(前根遍历,根左右遍历):
先遍历根节点,再遍历左节点,再遍历右节点,也就是说对于每一个树和每一个子树来说,根节点一定是在左节点的前面,左节点一定是在右节点的前面
3.后序遍历(后根遍历,左右根遍历):
先遍历左节点,再遍历右节点,再遍历根节点,也就是说对于每一个树和每一个子树来说,左节点一定在右节点后面,根节点一定在右节点后面
4.层序遍历
这种遍历方式是从上到下,从左往右进行树的遍历,需要借助一个辅助队列来完成。

对于前三种遍历方法都需要借助递归算法实现。

同样地,如果要计算出树的高度,也需要使用递归算法,树的高度等于左子树和右子树中的最大的那个高度 + 1.

计算树的高度算法如下:

int getTreeHeight(Tree tree) {
    if(tree == NULL){
        return 0;
    }
    //计算出左子树的高度
    int leftChildTreeHeight = getTreeHeight(tree->left);
    //计算出右子树的高度
    int rightChildTreeHeight = getTreeHeight(tree->right);
    return leftChildTreeHeight > rightChildTreeHeight ? leftChildTreeHeight + 1 : rightChildTreeHeight + 1;
}

根据遍历序列构造二叉树

根据二叉树以及某种遍历规则,可得出唯一的一种遍历顺序,但是给出一种遍历顺序,并不一定可以推出唯一的一种二叉树结构。如果可以确定唯一地一颗二叉树结构,那么必须有至少两种遍历方式,这两种遍历方式中,必须有中序遍历

  • 前序+中序遍历

如果前序遍历是 ADBCE
后序遍历是BDCAE

由于前序遍历第一个就是遍历的根节点,所以根节点是A,而在中序遍历中,A是第4个位置,由于中序遍历遵循的是左根右的规则,则说明BDC是A的左子节点,而E是A的右子节点,同理,递归以上,可勾出唯一的一个二叉树。

  • 后序+中序遍历

后序遍历的规则是左右根,所以根节点肯定是最后一个,左节点肯定是右节点前面。

后序遍历序列 : EFAHCIGBD
中序遍历序列:EAFDHCBGI

后序遍历最后一个节点必定是根节点,倒数第二个节点肯定是右子树的根节点,就如同前序遍历的第一个节点必定是根节点,第二个节点必定是左子树的根节点。那么可以确定出D是根节点,EAF是左子树的节点,HCBGD是右子树的节点。由于EAF是中序遍历,且右三个节点,那么A节点必为根节点,E节点为左子节点,F节点为右子节点。根据后序遍历的倒数第二个节点得出B是右节点的根节点,又根据中序遍历得HC为B得左子树,GI为B的右子树。而HC和GI都是两个节点,谁是父节点不好确定,中序遍历和后序遍历都是先遍历H再遍历C,说明肯定不能是C的父节点,因为如果H是父节点,那么后序遍历肯定是最后遍历H,那么现在需要确定H是C的左子节点还是右子节点,假设H是C的右子节点,那么中序遍历应该是CH,这样就不符合了,所以可以确定H为C的左子节点。同理可以确定出GI的位置。

  • 层序+中序

层序遍历第一个是根节点,所以可得出根节点在中序遍历的位置

层序序列:DABEFCGHI
中序序列:EAFDHCBGI

根据层序序列得出,D是根节点,那么EAF是D的左子树,因为A出现在层序遍历的第二个,所以A是左子树的根节点,E是A的左子节点,F是A的右子节点。在HCBGI中,根据层序遍历得出,B是根节点,且层序遍历中,先遍历的C,C是H的父节点,根据中序遍历得出H是C的左子节点,而GI在层序遍历中先出现的G,说明G是I的父节点,又因为中序遍历是GI,说明I是G的右子节点。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值