二叉树遍历

#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"
#include "iostream.h"
#define MAXSIZE 50  //定义堆栈的最大长度
int count=0;        //定义全局变量,保存叶子结点数
//定义二叉树结构
typedef struct Node{
 char data;    //数值
 struct Node *lchild; //左孩子
 struct Node *rchild; //右孩子
}BiTNode,*BiTree;

//定义堆栈结构
typedef struct {
 BiTree data[MAXSIZE];       //保存二叉树的地址
 int top;     //栈顶指针
}Stack;


void InitStack(Stack &s){
 s.top=-1;    //初始化堆栈,使其栈顶指针指向-1
}

//出栈  返回出栈内容
void Pop(Stack &s,BiTree &t){
 if(s.top!=-1){    //判断栈是否为空
  t=s.data[s.top];  //取出栈顶元素
  s.top--;    //重新设置栈顶指针指向位置
 }else{
  t=NULL;  
 }
}

//进栈
void Push(Stack &s,BiTree t){
 if(s.top==MAXSIZE){     //判断栈是否已满
  cout<<"栈已满!"<<endl;
 }else{
  s.top++;      //栈中元素:先加后赋值(指针先加1,后给指针所指位置赋值)
  s.data[s.top]=t;
 }
}

//判栈是否为空 true:是  false:否
bool StackEmpty(Stack s){
 if(s.top==-1)return true;
 else return false;
}


//创建二叉树   (每颗二叉树可以看做由多个子二叉树构成,而每个子二叉树的结构都是相似)
void CreateBiTree(BiTree &T){
 char ch;
 cin>>ch;        //输入二叉树每个结点的数据
 if(ch=='#') T=NULL;      //以#代表为空结点
 else{
  T=(BiTree)malloc(sizeof(BiTNode)); //分配空间
  T->data=ch;
  CreateBiTree(T->lchild);   //创建左孩子
  CreateBiTree(T->rchild);   //创建右孩子
 }
}

//判断二叉树结点
void Visit(char data){
 cout<<data<<"-"; 
}

//计算二叉树的叶子结点数
void Visit(BiTree T){
 if(!T->lchild&&!T->rchild){  //判断该二叉树的左孩子和右孩子是否为空,为空即为叶子结点
  count++;     //全局变量的叶子结点数增加1
 }
}

//计算二叉树的叶子结点数
int Leaf(BiTree T){
 if(!T)return 0;       //如果是空数,则返回0
 if(!T->lchild&&!T->rchild)return 1;  //如果是叶子结点,则返回1
 return Leaf(T->lchild)+Leaf(T->rchild); //左子树的结点数加上右子树的结点数
}


//中序遍历二叉树 先访问根结点的左孩子,然后是根结点,最后是右孩子
//递归遍历
void InOrder(BiTree T){
 if(T!=NULL){
  InOrder(T->lchild);
  Visit(T->data);  
  InOrder(T->rchild);
 }
}

//堆栈遍历
void InOrderS(BiTree T){
 Stack s;       //创建堆栈
 InitStack(s); 
 BiTree p;
 p=T;
 while(p!=NULL||!StackEmpty(s)){
  if(p){       //根结点不为空,则往根结点的左边走
   Push(s,p);     //记录,以便退回
   p=p->lchild;    //往左边走
  }else{
   Pop(s,p);     //退回到根结点
   Visit(p->data);    //访问根结点
   p=p->rchild;    //向根节点的右边走
  }  
 }
}

//先序遍历二叉树  先访问根结点,然后访问左孩子,最后访问右孩子
//递归遍历
void PreOrder(BiTree T){
 if(T!=NULL){
  Visit(T->data);Visit(T);
  PreOrder(T->lchild);
  PreOrder(T->rchild);
 }
}
//堆栈遍历    (堆栈中记录指针走过的记录)
void PreOrderS(BiTree T){
 BiTree p;
 p=T;
 Stack s;     //创建一个栈
 InitStack(s);
 while(p||!StackEmpty(s)){ //当当前结点不为空或是栈不为空时,可以继续循环 
        //结点不为空,则指针向左孩子方向走,否则,退回上一个根结点,并向根结点的右孩子方向走 
  if(p){
   Visit(p->data);  //先访问
   Push(s,p);   //进栈,记录指针走过的记录
   p=p->lchild;  //向左孩子方向走
  }else{
   Pop(s,p);   //退回根结点,即为出栈
   p=p->rchild;  //向根结点的右孩子方向走
  }
 }
}


//后序遍历二叉树  递归
void PostOrder(BiTree T){
 if(T!=NULL){
  PostOrder(T->lchild);
  PostOrder(T->rchild);
  Visit(T->data);
 }
}

//计算二叉树的高度
int PostTreeDepth(BiTree T){
 int hl,hr,max;
 if(!T)
  return 0;       //如果是空树,返回0
 else if(!T->lchild&&!T->rchild)   //如果是叶子结点,返回1
  return 1;
 else{
  hl=PostTreeDepth(T->lchild);  //求左子树的深度
  hr=PostTreeDepth(T->rchild);  //求右子树的深度
  max=hl>hr?hl:hr;     //得到左、右子树深度较大者
  return max+1;      //返回树的深度
 }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值