《大话数据结构》二叉树

1.定义

图6-5-2是一颗二叉树,6-2-1不是,因为D有三个子树

1)二叉树的特点

例子如下图所示,

2)特殊的二叉树

斜树

所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树
斜树有很明显的特点,就是每一层都只有一个结点,结点的个数与二叉树的深度相同 。
 

下图 中的树 2 就是左斜树,树 5 就是右斜树。
 

满二叉树

在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树
满二叉树的特点有 :

eg:

完全二叉树

满二叉树一定是一棵完全二叉树,但完全二叉树不一定是满的 。

定义:

只有图 6-5-6 中的树,尽管它不是满二叉树,但是编号是连续的,所以它是完全二叉树。
完全二叉树的特点是:

判断某二叉树是否是完全二叉树的办法?

心中默默给每个结点按照满二叉树的结构逐层顺序编号,如果编号出现空挡,就说明不是完全二叉树,否则就是。
 

2.二叉树的性质

性质 1 :在二叉树的第 i 层上至多有 21- 1 个结点 (i > 1 ) 。
eg:

性质 2: 深度为 k 的二叉树至多有 2飞1 个结点 (k :> l) 。
eg:

性质 3: 对任何一棵二叉树 T,如果其终端结点数为n0,度为 2 的结点数为n2,则n0=n2+1
终端结点数其实就是叶子结点数,我们设 n1 为度是 1 的结点数,则树 T 结点总数n=n2+n1+n0

例子如下图所示,

性质 4: 具有 n 个结点的完全二叉树的深度为

对于满二叉树而言,我们知道

那么么,

性质5:

对照下面的例子去学习,立马就懂了

3.二叉树的存储结构

1)顺序存储结构

二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,井且结点的存储位置,也就是数组的下标要能体现结点之间的逻辑关系
eg:

当然对于一般的二叉树,尽管层序编号不能反映逻辑关系,但是可以将其按完全二叉树编号,
缺点:

2)二叉链表

二叉树每个结点最多有两个孩子,所以设计一个数据域和两个指针域,这样的链表叫做二叉链表

data是数据域

lchild和rchild是指针域,存放指向左孩子和右孩子的指针
 

//二叉链表的结构定义
typedef struct bitnode
{
    int data;
    struct bitnode *lchild,*rchild;
    
}bitnode,*bitree

3.遍历二叉树

定义:

在这里我们可以简单地假定,访问就是输出结点的数据信息。
遍历方法的前提是:限制了从左至右的习惯方式

二叉树的定义是用递归的方式,所以,实现遍历算法也可以采用递归,而且极其简洁明了 。

这些遍历方法要结合代码,去感悟每个方法总结的话,才会有深刻理解。

1)前序遍历

规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树, 再前序遍历右子树。

遍历的顺序为: ABDGHCEIF。

typedef struct bitree
{
    int data;
    struct bitree *lchild,rchild;
}*bitree;

//前序遍历递归算法
void preorder(bitree T)
{
    if(NULL==T)
        return;
    printf("%c",T->data);
    preorder(T->lchild);
    preorder(T->rchild);
}

2)中序遍历

规则是若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点) ,中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树

遍历的顺序为 : GDHBAE ICF
 

typedef struct bitree
{
    int data;
    struct bitree *lchild,rchild;
}*bitree;

void inorder(bitree T)
{
    if(T==NULL)
        return;
    inorder(T->lchild);
    printf(""%c,T->data);
    inorder(T->rchild);
}

3)后序遍历

规则是若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点

遍历的顺序为 .: GHDBIEFCA
因为结点 G 无左右孩子,所以打印 G
 

typedef struct bitree
{
    int data;
    struct bitree *lchild,rchild;
}*bitree;

void postorder(bitree T)
{
     if(T==NULL)
        return;
    postorder(T->lchild);
    postorder(T->rchild);
    printf("%c",T->data);
}

4)层序遍历

规则是若树为空 , 则空操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,在同一层中 , 按从左到右的顺序对结点逐个访问
 

遍历的顺序为: ABCDEFGHL
 

eg:考察遍历二叉树的题目

已经复原了二叉树,要获得它的后序遍历结果就是易如反掌,结果是 CBEFDA .
 

二叉树遍历的性质:

4.二叉树的建立

假设二叉树的结点均为一个字符,我们把刚才前序遍历序列 AB#D##C##用键盘挨个输入
 

typedef struct bitree
{
    int data;
    struct bitree *lchild,*rchild;
}*bitree;

void creat()
{
    int ch;
    scanf("%c",&ch);
    if(ch=='#')
        *T=NULL;
    else{
        
        *T=(bitree)mallos(sizeod(bitnode));
        if(!*T)
            exit(OVERFLOW);
        (*T)->data=ch;//生成根节点
        creat(&(*T)->lchild);
        creat(&(*T)->rchild);    
    }
}

猜你喜欢

转载自blog.csdn.net/u011436427/article/details/81915770