二叉树及遍历方法

 

1.二叉树特点

1.1 二叉树的特点有:

  1. 每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。
  2. 左子树和右子树是有顺序的,次序不能任意颠倒。
  3. 即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。

二叉树具有五种基本形态: 1.空二叉树。 2.只有一个根结点。 3.根结点只有左子树。 4.根结点只有右子树。 5.根结点既有左子树又有右子树。

2.特殊二叉树

2.1 斜树

所有的结点都只有左子树的二叉树叫左斜树,如树2。

所有结点都是只有右子树的二叉树叫右斜树,如树5。这两者统称为斜树。

特点:就是每一层都只有一个结点,结点的个数与二叉树的深度相同。

2.2 满二叉树

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

 

满二叉树的特点有:(1)叶子只能出现在最下一层。出现在其他层就不可能达成平衡。(2)非叶子结点的度一定是2。(3)在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。

2.3 完全二叉树

对一棵具有n个结点的二叉树按层序编号,如果编号为i(1≤i≤n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。

 

完全二叉树的特点:(1)叶子结点只能出现在最下两层。(2)最下层的叶子一定集中在左部连续位置。(3)倒数二层,若有叶子结点,一定都在右部连续位置。(4)如果结点度为1,则该结点只有左孩子,即不存在只有右子树的情况。(5)同样结点数的二叉树,完全二叉树的深度最小。

3. 二叉树的性质

1、二叉树性质1

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

2、二叉树性质2

性质2:深度为k的二叉树至多有2k-1个结点(k≥1)。

3、二叉树性质3

性质3:对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。

终端结点数其实就是叶子结点数,而一棵二叉树,除了叶子结点外,剩下的就是度为1或2的结点数了,我们设n1为度是1的结点数。则树T结点总数n=n0+n1+n2

4、二叉树性质4

性质4:具有n个结点的完全二叉树的深度为|log2n+1|(|x|表示不大于x的最大整数)。

5、二叉树性质5

性质5:如果对一棵有n个结点的完全二叉树(其深度为)的结点按层序编号(从第1层到第层,每层从左到右),对任一结点i(1≤i≤n)有:

1.如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点。

2.如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i。

3.如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。

这是一个完全二叉树,深度为4,结点总数是10。

对于第一条来说是很显然的,i=1时就是根结点。i>1时,比如结点7,它的双亲就是,结点9,它的双亲就是。

第二条,比如结点6,因为2×6=12超过了结点总数10,所以结点6无左孩子,它是叶子结点。同样,而结点5,因为2×5=10正好是结点总数10,所以它的左孩子是结点10。

第三条,比如结点5,因为2×5+1=11,大于结点总数10,所以它无右孩子。而结点3,因为2×3+1=7小于10,所以它的右孩子是结点7。

4 二叉树的存储结构

1 二叉树顺序存储结构

顺序存储结构一般只用于完全二叉树。

2 二叉链表

既然顺序存储适用性不强,我们就要考虑链式存储结构。

其中data是数据域,lchild和rchild都是指针域,分别存放指向左孩子和右孩子的指针。

以下是我们的二叉链表的结点结构定义代码。

/* 二叉树的二叉链表结点结构定义 */
/* 结点结构 */
typedef struct BiTNode                  
{
    /* 结点数据 */
    TElemType data;                     
    /* 左右孩子指针 */
    struct BiTNode *lchild, *rchild;    
} BiTNode, *BiTree;

结构示意图如图6-7-5所示。

遍历二叉树

1 二叉树遍历原理

二叉树的遍历(traversing binary tree)是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。

这里有两个关键词:访问和次序。

2 二叉树遍历方法

2.1 前序遍历(根--左--右)

规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。如图6-8-2所示,遍历的顺序为:ABDGH-CEIF。

 

2.2 中序遍历(左--根--右)

规则是若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。如图6-8-3所示,遍历的顺序为:GDHBAE-ICF。

2.3  后序遍历(左--右--根)

规则是若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。如图6-8-4所示,遍历的顺序为:GHDBIEFCA。

2.4   层序遍历(根结点开始访问,从上而下逐层遍历)

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

3 前序遍历算法(根--左--右)

二叉树的定义是用递归的方式,所以,实现遍历算法也可以采用递归,而且极其简洁明了。先来看看二叉树的前序遍历算法。代码如下:

/* 二叉树的前序遍历递归算法 */
void PreOrderTraverse(BiTree T)
{
    if (T == NULL)
        return;
    /* 显示结点数据,可以更改为其他对结点操作 */
    printf("%c", T->data);          
    /* 再先序遍历左子树 */
    PreOrderTraverse(T->lchild);    
    /* 最后先序遍历右子树 */
    PreOrderTraverse(T->rchild);    
}

4 中序遍历算法(左--根--右)

/* 二叉树的中序遍历递归算法 */
void InOrderTraverse(BiTree T)
{
    if (T == NULL)
        return;
    /* 中序遍历左子树 */
    InOrderTraverse(T->lchild);    
    /* 显示结点数据,可以更改为其他对结点操作 */
    printf("%c", T->data);         
    /* 最后中序遍历右子树 */
    InOrderTraverse(T->rchild);    
}

5 后序遍历算法(左--右--根)

/* 二叉树的后序遍历递归算法 */
void PostOrderTraverse(BiTree T)
{
    if (T == NULL)
        return;
    /* 先后序遍历左子树 */
    PostOrderTraverse(T->lchild);    
    /* 再后序遍历右子树 */
    PostOrderTraverse(T->rchild);    
    /* 显示结点数据,可以更改为其他对结点操作 */
    printf("%c", T->data);           
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值