首先,可以确定先序、中序和后序递归遍历,先建立二叉树进行遍历。
首先,先建立二叉树,进行先序、中序和后序递归遍历。
/**二叉树的建立--按照先序方式建立--插入**/
void CreateBiTree(BiTree &T)
{
char val;//节点的数据类型
scanf("%c",&val);
if(val == '#')
T = NULL; //null表示为空枝
else
{
T = (BiTree)malloc(sizeof(BiTreeNode));
T->data = val;
CreateBiTree(T->left);//构造左子树
CreateBiTree(T->right);//构造右子树
}
}
/**先序遍历 根左右**/
void PreOrderTravel(BiTree T)
{
if(T==NULL)
return;
printf("%c ",T->data);
PreOrderTravel(T->left);
PreOrderTravel(T->right);
}
/**中序遍历 左根右**/
void InOrderTravel(BiTree T)
{
if(T==NULL)
return;
InOrderTravel(T->left);
printf("%c ",T->data);
InOrderTravel(T->right);
}
/**后序遍历 左右根**/
void TailOrderTravel(BiTree T)
{
if(T==NULL)
return;
TailOrderTravel(T->left);
TailOrderTravel(T->right);
printf("%c ",T->data);
}
接着,遍历中序非递归遍历,我们利用构建栈来实现,先实现栈的基本功能。
/**构造一个空栈**/
Status InitStack(SqStack &S)
{
//1.申请空间
S.base =(BiTree*)malloc(STACK_INIT_SIZE * sizeof(BiTree));
if(!S.base) exit(0);//储存空间分配失败
S.top=S.base; //栈底和栈顶指针指向同一块内存
S.stacksize= STACK_INIT_SIZE;
return OK;
}
/**插入元素e为新的栈顶元素(入栈操作)**/
Status Push(SqStack &S,BiTree e)
{
//满不满,若满追加存储空间
if(S.top-S.base==S.stacksize)
{
//重新初始化
S.base=(BiTree*)realloc(S.base,(S.stacksize + STACKINCREMENT)* sizeof(BiTree));
if(!S.base) exit(0);
S.top=S.base+ S.stacksize;
S.stacksize += STACKINCREMENT;
}
//元素e入栈
*S.top=e;
S.top++;//栈顶指针指向下一个
return OK;
}
/**若栈不空,则删除S的栈顶元素,用e为返回其值(出栈操作)**/
Status Pop(SqStack &S,BiTree &e)
{
//1.判断
if(S.top==S.base) return ERROR;
S.top--;
e=*S.top;
return OK;
}
/**若栈S空,则返回1,若不空返回0(判空操作)**/
Status StackEmpty(SqStack S)
{
//判断栈是否为空
if(S.top==S.base)
return 1;
else;
return 0;
}
进行中序非递归遍历。
/**中序遍历非递归**/
void InOrderTravel_n(BiTree T)
{
SqStack S;
InitStack(S);
BiTreeNode *p=T;
while(p||!StackEmpty(S)){
if(p){
Push(S,p);
p=p->left;
}
else{
Pop(S,p);
printf("%c ",p->data);
p=p->right;
}
}
return ;
}
统计二叉树叶子节点和高度。
/* 计算度为0的结点*/
void CountNode0(BiTree T)
{
if(T==NULL)
return ;
CountNode0(T->left);
CountNode0(T->right);
if(T->left==NULL&&T->right==NULL)
count0++;
}
/*求二叉树高度*/
int height(BiTree T)
{
int L,R;
if(T==NULL)
return 0;
L= height(T->left);
R=height(T->right);
return L>R ?(L +1) :(R +1);
}
完整代码:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100//存储空间初始分配量
#define STACKINCREMENT 10//存储空间分配增量
typedef int Status;//函数返回值状态
int count0=0;
/**二叉树数据结构定义**/
typedef struct BiTreeNode
{
char data;
struct BiTreeNode *left;
struct BiTreeNode *right;
}BiTreeNode,*BiTree;
/*********************************************栈的操作部分************************************/
/**栈的顺序结构定义**/
typedef struct stack
{
BiTree*base;//栈底指针
BiTree*top;//栈顶指针
int stacksize;//当前栈空间的最大容量
}SqStack;//顺序栈
//基本操作(函数声明部分)
Status InitStack(SqStack &S); //构造一个空栈
Status Push(SqStack &S,BiTree e);//入栈操作
Status Pop(SqStack &S,BiTree &e);//出栈操作
Status StackEmpty(SqStack S);//判断栈是否为空
void CreateBiTree(BiTree &T);//二叉树的初始化
void PreOrderTravel(BiTree T);//先序递归遍历
void InOrderTravel(BiTree T);//中序递归遍历
void TailOrderTravel(BiTree T);//后序递归遍历
void InOrderTravel_n(BiTree T);//中序非递归遍历
void CountNode0(BiTree T);//计算度为0的结点
int height(BiTree T) ;//求二叉树高度
void Menu();//显示菜单信息
/**构造一个空栈**/
Status InitStack(SqStack &S)
{
//1.申请空间
S.base =(BiTree*)malloc(STACK_INIT_SIZE * sizeof(BiTree));
if(!S.base) exit(0);//储存空间分配失败
S.top=S.base; //栈底和栈顶指针指向同一块内存
S.stacksize= STACK_INIT_SIZE;
return OK;
}
/**插入元素e为新的栈顶元素(入栈操作)**/
Status Push(SqStack &S,BiTree e)
{
//满不满,若满追加存储空间
if(S.top-S.base==S.stacksize)
{
//重新初始化
S.base=(BiTree*)realloc(S.base,(S.stacksize + STACKINCREMENT)* sizeof(BiTree));
if(!S.base) exit(0);
S.top=S.base+ S.stacksize;
S.stacksize += STACKINCREMENT;
}
//元素e入栈
*S.top=e;
S.top++;//栈顶指针指向下一个
return OK;
}
/**若栈不空,则删除S的栈顶元素,用e为返回其值(出栈操作)**/
Status Pop(SqStack &S,BiTree &e)
{
//1.判断
if(S.top==S.base) return ERROR;
S.top--;
e=*S.top;
return OK;
}
/**若栈S空,则返回1,若不空返回0(判空操作)**/
Status StackEmpty(SqStack S)
{
//判断栈是否为空
if(S.top==S.base)
return 1;
else;
return 0;
}
/*********************************************二叉树的操作部分************************************/
/**二叉树的建立--按照先序方式建立--插入**/
void CreateBiTree(BiTree &T)
{
char val;//节点的数据类型
scanf("%c",&val);
if(val == '#')
T = NULL; //null表示为空枝
else
{
T = (BiTree)malloc(sizeof(BiTreeNode));
T->data = val;
CreateBiTree(T->left);//构造左子树
CreateBiTree(T->right);//构造右子树
}
}
/**先序遍历 根左右**/
void PreOrderTravel(BiTree T)
{
if(T==NULL)
return;
printf("%c ",T->data);
PreOrderTravel(T->left);
PreOrderTravel(T->right);
}
/**中序遍历 左根右**/
void InOrderTravel(BiTree T)
{
if(T==NULL)
return;
InOrderTravel(T->left);
printf("%c ",T->data);
InOrderTravel(T->right);
}
/**后序遍历 左右根**/
void TailOrderTravel(BiTree T)
{
if(T==NULL)
return;
TailOrderTravel(T->left);
TailOrderTravel(T->right);
printf("%c ",T->data);
}
/**中序遍历非递归**/
void InOrderTravel_n(BiTree T)
{
SqStack S;
InitStack(S);
BiTreeNode *p=T;
while(p||!StackEmpty(S)){
if(p){
Push(S,p);
p=p->left;
}
else{
Pop(S,p);
printf("%c ",p->data);
p=p->right;
}
}
return ;
}
/* 计算度为0的结点*/
void CountNode0(BiTree T)
{
if(T==NULL)
return ;
CountNode0(T->left);
CountNode0(T->right);
if(T->left==NULL&&T->right==NULL)
count0++;
}
/*求二叉树高度*/
int height(BiTree T)
{
int L,R;
if(T==NULL)
return 0;
L= height(T->left);
R=height(T->right);
return L>R ?(L +1) :(R +1);
}
/*打印二叉树操作菜单 */
void Menu( )
{
printf("-----------1:先序遍历二叉树-----------------------------------\n");
printf("-----------2:中序遍历二叉树-----------------------------------\n");
printf("-----------3:后序遍历二叉树-----------------------------------\n");
printf("-----------4:中序遍历二叉树(非递归算法)---------------------\n");
printf("-----------5:统计二叉树中叶子个数-----------------------------\n");
printf("-----------6:统计二叉树的高度---------------------------------\n");
printf("-----------7:查看二叉树所有遍历、叶子个数和高度---------------\n");
printf("-----------8:结束对二叉树的操作-------------------------------\n");
}
int main()
{
int i;//选择
BiTree T;
T = (BiTree)malloc(sizeof(BiTreeNode));
printf("请给二叉树按照先序方式依次输入结点的值(空结点为#):\n");
CreateBiTree(T);
//显示二叉树操作菜单
printf("===================================菜单=========================================\n");
while(1)
{
Menu();
printf("请输入你的选择:");
scanf("%d",&i);
switch(i)
{
case 1:
printf("先序方式遍历结果:\n");
PreOrderTravel(T);
printf("\n");
break;
case 2:
printf("中序方式遍历结果:\n");
InOrderTravel(T);
printf("\n");
break;
case 3:
printf("后序方式遍历结果:\n");
TailOrderTravel(T);
printf("\n");
break;
case 4:
printf("中序非递归遍历二叉树结果为:\n");
InOrderTravel_n(T);
printf("\n");
break;
case 5:
CountNode0(T);
printf("叶子节点共%d个\n",count0);
count0=0;
printf("\n");
break;
case 6:
printf("二叉树的高度:%d\n",height(T));
break;
case 7:
printf("先序方式遍历结果:\n");
PreOrderTravel(T);
printf("\n");
printf("中序方式遍历结果:\n");
InOrderTravel(T);
printf("\n");
printf("后序方式遍历结果:\n");
TailOrderTravel(T);
printf("\n");
printf("中序非递归遍历二叉树结果为:\n");
InOrderTravel_n(T);
printf("\n");
printf("叶子结点结果:\n");
CountNode0(T);
printf("共%d个\n",count0);
count0=0;
printf("二叉树的高度:%d\n",height(T));
printf("\n");
break;
case 8:exit(1);break;
default:printf("请输入合法的选择值\n");
}
}
}
结果如图: