二叉树

二叉树(Binary Tree)

概念:

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

特点:

  • 每个结点最多有两棵子树
  • 左子树和右子树是有顺序的
  • 即使树中某结点只有一颗子树,也要区分它是左子树还是右子树

特殊的二叉树:

  • 满二叉树:在一颗二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上。
  • 完全二叉树:对于一棵具有n个节点的二叉树按照层次编号,同时,左右子树按照先左后右编号,如果编号为i的节点与同样深度的满二叉树中编号为i的节点在二叉树中的位置完全相同,则这棵二叉树称为完全二叉树。

性质:

  • 在二叉树的第i层中至多有2^(i-1)个结点
  • 深度为k的二叉树至多有(2^k)-1个结点
  • 对一棵二叉树,如果叶子节点的个数为n0,度为2的节点个数为n2,则n0=n2+1
  • 具有n个结点的完全二叉树的深度为[log2n]+1
  • 对于一棵有n个结点的完全二叉树的结点按层序号,对任意结点i有
    • 如果i = 1,则结点i是二叉树的根,无双亲;如果i>1,则双亲是结点(i/2)
    • 如果2i>n,则结点i无左右孩子;否则其左右孩子是结点2i
    • 如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1

链式存储结构

typedef int TElemType;

typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;

二叉树的遍历

  • 前序遍历:若二叉树为空,则返回;否则先访问根节点,然后前序遍历左子树,再遍历右子树。

    void PreOrderTraverse(BiTree T)
    {
        if(T == NULL)
            return;
        printf("%d",T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
    
  • 中序遍历:若二叉树为空,则返回;否则从根结点开始,中序遍历跟结点的左子树,然后访问根节点,最后中序遍历右子树

    void InOrderTraverse(BiTree T)
    {
        if(T == NULL)
            return
        PreOrderTraverse(T->lchild);
        printf("%d",T->data);
        PreOrderTraverse(T->rchild);
    }
    

  • 后续遍历:若二叉树为空,则返回;否则从左子树到右子树后结点的方式遍历访问左右子树,最后访问根节点

    void PostOrderTraverse(BiTree T)
    {
        if(T == NULL)
            return
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
        printf("%d",T->data);
    }
    

经典应用:

赫夫曼树、编码