#include <stdio.h>
#include <stdlib.h>
/*二叉树顺序存储结构*/
#define MAXSIZE 100
typedef char SqBiTree[MAXSIZE];//以数组的形式存储
SqBiTree bt;
/*二叉树链式存储结构*/
typedef struct BiTNode{
char data;//数据域
struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;//初始化树的函数
/*栈的相关定义*/
#define STACKINITSIZE 50//栈初始空间大小
#define INCREASEMENT 50//栈空间大小的增量
typedef struct SqStack
{//定义顺序栈结构
BiTNode *base;//栈底指针
BiTNode *top;//栈顶指针
int stacksize;//顺序栈空间大小
}SqStack;
int InitStack(SqStack *S)
{//建立一个空栈,建立成功,返回1,失败,返回0
S->base = (BiTNode*)malloc(STACKINITSIZE * sizeof(BiTNode));
if(!S->base)
return 0;
S->top = S->base = 0;
S->stacksize = STACKINITSIZE;
return 1;
}
int Push(SqStack *S,BiTNode e)
{//进栈操作
if(S->top - S->base >= S->stacksize)
{
S->base = (BiTNode*)realloc(S->base,(STACKINITSIZE + INCREASEMENT) * sizeof(BiTNode));
if(!S->base)
return 0;
S->stacksize = 30;
}
*S->top = e;
S->top ++;
return 1;
}
int Pop(SqStack *S,BiTNode *e)
{//出栈操作,若栈为空,则返回0;栈不为空,则返回1
if(S->base == S->top == 0)
return 0;
e = --S->top;
return 1;
}
/*用链式方式来构造二叉树*/
void CreateBiTreeLink(BiTree *T){
(*T)=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->data='F';
(*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->data='B';
(*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->lchild->data='A';
(*T)->lchild->lchild->lchild=NULL;
(*T)->lchild->lchild->rchild=NULL;
(*T)->lchild->rchild->data='D';
(*T)->lchild->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->rchild->lchild->data='C';
(*T)->lchild->rchild->rchild->data='E';
(*T)->lchild->rchild->lchild->lchild=NULL;
(*T)->lchild->rchild->lchild->rchild=NULL;
(*T)->lchild->rchild->rchild->lchild=NULL;
(*T)->lchild->rchild->rchild->rchild=NULL;
(*T)->rchild->data='G';
(*T)->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->lchild=NULL;
(*T)->rchild->rchild->data='I';
(*T)->rchild->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->rchild->rchild=NULL;
(*T)->rchild->rchild->lchild->data='H';
(*T)->rchild->rchild->lchild->lchild=NULL;
(*T)->rchild->rchild->lchild->rchild=NULL;
}//模拟操作结点元素的函数,输出结点本身的数值
/*用顺序存储方式构造二叉树*/
void CreateBiTreeOrder(BiTNode *T)
{//此处是二叉树的前序遍历方式创建,如果要使用中序或者后序的方式建立二叉树,只需将生成结点和构造左右子树的顺序改变即可
char ch;
scanf("%c",&ch);//将从终端输入的字符传进ch中
if(ch=='#')//#表示空结点
T=NULL;//遇到#,T也赋值为空
else
{
T=(BiTree)malloc(sizeof(BiTNode));//否则生成一个空间
if(!T)//若无法生成则退出
exit(-1);
T->data=ch;//否则将ch的值赋值给T空间的data域
CreateBiTreeOrder(T->lchild);//用递归指向T的左孩子,重复操作
CreateBiTreeOrder(T->rchild);//左孩子全赋值完后到右孩子
}//先序读取数据,根左右
}
/*递归后序遍历*/
void PostOrderTraverse(BiTNode *T){
if (T) {
PostOrderTraverse(T->lchild);//遍历左孩子
PostOrderTraverse(T->rchild);//遍历右孩子
printf("%c ",T->data);//访问根节点
}//如果结点为空,返回上一层
}
/*非递归中序遍历*/
int InOrderTraverse(BiTNode *T){
BiTNode *p,*e; //p指针用于代替T进行操作,e指针用于返回出栈的值
SqStack S; //S为空栈
InitStack(&S); //初始化栈S
p=T; //p指向T的位置
while(p!=0||S.top!=0) //p结点不为空或栈不空时执行循环操作
{
if(p!=0) //栈空但p结点不空
{
Push(&S,*p); //p结点入栈
p=p->lchild; //p指针指向其左孩子
}
else //p结点为空但栈不空
{
Pop(&S,e); //弹出栈中结点并返回其值
printf("%c ",e->data); //打印返回结点的数据
p=e->rchild; //p指针指向根结点的右孩子
}
}//while 一直到p指针空且栈空
return 1;
}
int main() {
printf("BiTree start:\n"); //链式二叉树遍历开始
BiTree Tree;
CreateBiTreeLink(&Tree); //生成链式二叉树
printf("PostOrderTraverse:\n"); //打印递归后序遍历结果
PostOrderTraverse(Tree);
printf("\nInOrderTraverse:\n"); //打印非递归中序遍历结果
InOrderTraverse(Tree);
printf("SqBiTree start:\n"); //顺序二叉树遍历开始
BiTNode T;
printf("scanf PreOrderTraverse:"); //先序读入FBA##DC##E##G#IH###
CreateBiTreeOrder(&T); //构造二叉树
printf("printf PostOrderTraverse:\n"); //打印递归后序遍历结果
PostOrderTraverse(&T);
printf("printf InOrderTraverse:\n"); //打印非递归中序遍历结果
InOrderTraverse(&T);
}
实验完成后老师点评:
读取可以使用双亲存储或者孩子链表存储不用每一个都手动输入。