树的定义:

  • 树是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合
  • (1)每个结点有零个或多个子结点
  • (2)没有父节点的结点称为根节点
  • (3)每一个非根结点有且只有一个父节点
  • (4)除了根结点外,每个子结点可以分为多个不相交的子树。

用到的术语:

 

  • 结点的度:结点拥有的子树的数目
  • 叶子结点:度为0的结点
  • 分支结点:度不为0的结点
  • 树的度:树中结点的最大的度
  • 层次:根结点的层次为1,其余结点的层次等于该结点的双亲结点的层次加1
  • 树的高度:树中结点的最大层次
  • 森林:0个或多个不相交的树组成。对森林加上一个根,森林即成为树;删去根,树即成为森林

 

二叉树:

  • 定义:
  • 二叉树是每个结点最多有两个子树的树结构。它有五种基本形态:二叉树可以是空集;根可以有空的左子树或右子树;或者左、右子树皆为空。
  • 性质:
  • 性质1:二叉树第i层上的结点数目最多为2i-1(i>=1)
  • 性质2:深度为k的二叉树至多有2k-1个结点(k>=1)
  • 性质3:包含n个结点的二叉树的高度至少为(log2n)+1
  • 性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1

满二叉树,完全二叉树:

  • 满二叉树,度为0和2的二叉树;
  • 完全二叉树,只有最下面两层节点,度小于2的二叉树;
  • 完全二叉树,若设二叉树的高度为h,除第h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
  • 完全二叉树,度为1的节点要么为0,要么为1。

一些性质:

  • 如果一棵完全二叉树的结点总数为n,那么叶子结点等于n/2(当n为偶数时)或者(n+1)/2(当n为奇数时)
  • 定义n为节点总个数,n0是度为0的个数,n1是度为1的个数,n2是度为2个数。
  • 则有n=n0*0+n1*1+n2*2+1 ; n = n0+n1+n2
  • n0=n2+1。

树表示:多叉树转成二叉树

  • 一个节点的结构:left(指向孩子),data,right(指向兄弟);左孩子右兄弟

树的存储:

  • 数组中:还原困难;
  • 链表中:指针域的个数不定;
  • 解决方案,把无序树转换成二叉树,然后两个指针域,左孩子右兄弟。
  • 二叉链表示法:一个data域,两个指针域,左孩子右兄弟
  • 三叉链表表示法:可以由孩子找到父亲
  • 双亲表示法:可以存储不规则的树

数的遍历:      树:a(b(d,e),c(f,g))

  • 先序:根,左子树,右子树   顺序:a,b,d,e,c,f,g
  • 中序:左子树,根,右子树   顺序:d,b,e,a,f,c,g
  • 后序:左子树,右子树,根   顺序:d,e,b,f,g,c,a 
//先序遍历
void xianxuBL(BiTNode * root)
{
    //递归结束的条件
    if (root == NULL)
    {
        //空节点结束
        return;
    }
    
    //访问根节点
    printf("%c", root->data);
    //遍历左子树
    xianxuBL(root->lChild);
    //遍历右子树
    xianxuBL(root->rChild);
}
//中序遍历
void zhongxuBL(BiTNode * root)
{
    //递归结束的条件
    if (root == NULL)
    {
        //空节点结束
        return;
    }

    //遍历左子树
    zhongxuBL(root->lChild);
    
    //访问根节点
    printf("%c", root->data);
    
    //遍历右子树
    zhongxuBL(root->rChild);
}
//后序遍历
void houxuBL(BiTNode * root)
{
    //递归结束的条件
    if (root == NULL)
    {
        //空节点结束
        return;
    }

    //遍历左子树
    houxuBL(root->lChild);

    //遍历右子树
    houxuBL(root->rChild);

    //访问根节点
    printf("%c", root->data);
}