二叉树T:一个有穷的结点集合,这个集合可以为空,若不为空,则它是由根结点和称为其左子树TL和右子树TR的 两个不相交的二叉树组成。 

  二叉树五种基本形态:空树,只有根结点,右子树为空,左子树为空,左右子树均不为空树。

一、二叉树的几个重要性质

  1、设二叉树的根结点为第一层二叉树第i层的最大结点数是2i-1,i>=1;

  设二叉树的根结点深度为1深度为k的二叉树最大结点总数为2k-1,k>=1;

  (关于树的层、深度,上面是浙大数据结构的说法,也有定义根结点的层数为0,深度为0,从上向下增长;叶结点高度为0,从下向上增长。)

  2、对于任何非空二叉树,叶子结点的个数,等于度为2的非叶子结点的个数+1,即n0 = n2 + 1

  3、满二叉树(full binary trees),在树中,每个中间结点有且仅有两个孩子结点。

  4、完全二叉树(complete binary trees),具有n个结点的完全二叉树的深度为log2n + 1;

  完全二叉树每个结点的左子树的深度 - 右子树的深度等于0或1,即叶结点只可能出现在最下层或次最下层

  满二叉树一定是完全二叉树,反之不成立;

  若对n个结点的完全二叉树从上到下且从左到右进行1至n编号,则对完全二叉树中任意一个编号为i的结点:

    1、)若i = 1,则该结点是二叉树的根,无双亲结点,否则 i/2 的结点为其双亲结点;

    2、)若2i<=n,则,编号为2i的结点为其左孩子结点,否则,该结点无左孩子结点;

    3、)若2i+1<=n,则,编号为2i+1的结点为其右孩子结点,否则,该结点无右孩子结点;

  设一颗完全二叉树有1000个结点,问:有多少个叶子结点;有多少个度为2的结点;有多少个结点只有非空左子树

  因为完全二叉树是从上到下,且从左到右进行编号的,因此,只有非空左子树的结点只可能有一个,根据二叉树的性质,1000 = n0 + n1 + n2 = 2*n2 + 1 +  n1,如果n1为1,998能为2整除,所以n1 = 1,n2 = 499,n0 = n2 + 1 = 500

  5、设深度为d(只有一个根结点时,d为1)的二叉树只有度为0和2的结点,则此类二叉树的结点数至少为2d-1

  证明:d为1的时候,至少有1个,2*1 -1;

  d为2的时候,没有度为1的点,情况为至少为3个 = 2*2 -1;

  d大于2的时候,由于没有度为1的点,所以每增加一层,每层至少增加两个

  设d-1层的公式:2*(d -1) - 1,第d层的就是2*(d -1) - 1 +2,所以d层结点数至少为2*d - 1

二、二叉树的抽象数据类型定义

  类型名称:二叉树

  数据对象集:一个有穷的结点集合。 若不为空,则由根结点和其左、右二叉子树组成。

  操作集: BT ∈ BinTree, Item ∈ ElementType,重要操作有:

  1、Boolean IsEmpty( BinTree BT ): 判别BT是否为空;

  2、void Traversal( BinTree BT ):遍历,按某顺序访问每个结点;

  3、BinTree CreatBinTree( ):创建一个二叉树。

三、二叉树的存储结构

  1、顺序存储结构

  完全二叉树:按从上至下、从左到右顺序存储,n个结点的完全二叉树的结点父子关系:  非根结点(序号 i > 1)的父结点的序号是 i / 2; 结点(序号为 i )的左孩子结点的序号是 2i, (若2 i <= n,否则没有左孩子);  结点(序号为 i )的右孩子结点的序号是 2i+1, (若2 i +1<= n,否则没有右孩子);

  一般二叉树也可以采用这种结构,但会造成空间浪费

  2、链式存储结构

typedef int ElementType;
typedef struct TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};