16、二叉树的遍历

一、相关概念

0、树的结点包含一个数据元素及若干指向其子树的分支;

1.、树的结点:包含一个数据元素和指向其子树的所有分支;

2.、结点的度:一个结点拥有的子树个数,度为零的结点称为叶结点;

3.、树的度:树中所有结点的度的最大值 Max(D(I));

    含义:树中最大分支数为树的度;

4.、结点的层次及树的深度:根为第一层,根的孩子为第二层,若某结点为第k层,则其孩子为k+1层;

   树中结点的最大层次称为树的深度或高度;

5、森林:是m(m>=0)棵互不相交的树的集合;

   森林与树概念相近,相互很容易转换;

6 、有序树、无序树  如果树中每棵子树从左向右的排列拥有一定的顺序,不得互换,则称为有序树,否则称为无序树。

7、二叉树(BinaryTree)是n(n≥0)个结点的有限集。它或者是空集(n=0),或者同时满足以下两个条件:

  

(1) 有且仅有一个根结点;

    (2) 其余的结点分成两棵互不相交的左子树和右子树。

  

二叉树与树有区别:树至少应有一个结点,而二叉树可以为空;树的子树没有顺序,但如果二叉树的根结点只有一棵子树,必须明确区分它是左子树还是右子树,因为两者将构成不同形态的二叉树。因此,二叉树不是树的特例。它们是两种不同的数据结构。

8、两种特殊形态的二叉树

(1) 满二叉树(FullBinaryTree) 

   深度为k,且有2k-1个结点的二叉树。

    特点:(1)每一层上结点数都达到最大;

                (2)度为1的结点n1=0,树叶都在最下一层上。

(2) 完全二叉树(Complete BinaryTree)  

    深度为k,结点数为n的二叉树,当且仅当每个结点的编号都与相同深度的满二叉树中从1到n的结点一一对应时,称为完全二叉树。

  

完全二叉树的特点:

  

(1)每个结点i的左子树的深度Lhi-其结点i的右子树的深度Rhi等于0或1,即叶结点只可能出现在层次最大或次最大的两层上。

  

(2)完全二叉树结点数n满足2k-1-1<n≤2k-1 

(3)满二叉树一定是完全二叉树,反之不成立。

9、二叉树的性质

  

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

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

       (深度一定,二叉树的最大结点数也确定)

 性质3  二叉树中,终端结点数n0与度为2的结点数n2有如下关系:  

        n0=n2+1

 性质4  结点数为n的完全二叉树,其深度为以2为底的Log(n)加1。

存储结构如下:

typedef struct node

{ ElemType data;

    struct node *lchild;

    struct node *rchild;

} BTree,*tree; 

  其中,tree是指向根结点的指针。 

  

性质5  具有n个结点的二叉链表中,共有2n个指针域。其中只有n-1个用来指示结点的左、右孩子,其余的n+1个指针域为空。

二、遍历算法

  

分中序(前缀表示,也称波兰式),中序(中缀表示),后序(后缀表示,也称逆波兰式)三咱遍历方法。

  

先序:

  

preorder(BTree *root)         //前序遍历

  

{ if(root!= NULL)             //如果不是空结点

  

 { printf(“%c\n”,root->data); //输出当前结点值

  

  preorder(root->lchild);    //递归前序遍历左子结点

  

  preorder(root->rchild);    //递归前序遍历右子结点

  

 }

 return;                      //结束

  

 }

中序:

  

void inorder(BTree *root)       //中序遍历

  

{ if(root!=NULL)               //如果不是空结点

  

  { inorder(root->lchild);     //递归中序遍历左子结点

  

  printf(“%c\n”,root->data);  //输出当前结点值

  

    inorder(root->rchild);      //递归中序遍历右子结点

  

   }

 }

后序:

  

void postorder(BTree *root)   //后序遍历

  

{ if(root!=NULL)                //如果不是空结点

  

 { postorder(root->lchild);     //递归后序遍历左子结点

  

   postorder(root->rchild);     //递归后序遍历右子结点  

  

   printf(“%c\n”,root->data);   //输出当前结点值

  

  }

}

 

Status inorder(BiTree root)

{//中序遍历非递归算法

SqStack S;

InitStack(S);

Push(S,root);

BiTree p;

while(!StackEmpty(S))

  {

   while(GetTop(S,p)&&p)  Push(S,p->lchild);

   Pop(S,p);  //空指针退栈

   if(!StackEmpty(S))

    {

    Pop(S,p);

       printf("%c\n",p->data);

       Push(S,p->rchild);

    }//if

  }//while

return ok;

}

 

三、算法实现(举个例子)

#include "stdio.h"

#include "stdlib.h"

 

typedef char ElemType3;

typedef  int Status; 

#define ok 1

#define error 0

int count=0;

typedef struct BiTNode         //定义链表结构

 ElemType3 data;             //定义结点值

 struct BiTNode *lchild;       //定义左子结点指针

 struct BiTNode *rchild;       //定义右子结点指针

}BiTNode,*BiTree;

 

Status preorder(BiTree root)

{

if(root!=NULL)

  {

   printf("%c\n",root->data);

   preorder(root->lchild);

   preorder(root->rchild);

  }//

return ok;

}

 

Status inorder(BiTree root)

{

if(root!=NULL)

  {

   inorder(root->lchild);

   printf("%c\n",root->data);

   inorder(root->rchild);

  }//

return ok;

}

 

 

Status CreateBitree(BiTree &T)

{//按先序次序输入二叉树

char ch,enter;

scanf("%c%c",&ch,&enter);

if(ch==' ') T=NULL;

else{

    if(!(T=(BiTNode*)malloc(sizeof(BiTNode)))) exit(1);

       T->data=ch; 

       CreateBitree(T->lchild);

       CreateBitree(T->rchild);

    }//else

return ok;

}//CreateBitree

 

int main()

{

BiTree T;       

CreateBitree(T);

preorder(T);

inorder(T);

return 1;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值