#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; //返回树的深度
}
}