/* ****************二叉树有关算法*************** */
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#define stackinitsize 100
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int TElemType ;
typedef int Status;
//一一一一一二叉树的二叉链表存储表示一一一一一
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild; //左右孩子指针
}BiTnode,*SElemType,*BiTree;
typedef struct{
//该堆栈的元素是指针类型的
//base和top均是指向指针的指针
SElemType *base;
SElemType *top;
int stacksize;
}sqstack;//堆栈结构
//一一一一一基本操作的函数原型说明(部分)一一一一一
Status CreateBitree(BiTree &T);
//按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树。
//构造二叉链表表示的二叉树T.
Status PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e));
//采用二叉链表存储结构,visit是对结点操作的应用函数。
//先序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
//一旦visit()失败,则操作失败。
Status InorderTraverse(BiTree T,Status(*Visit)(TElemType e));
//采用二叉链表存储结构,Visit是对结点操作的应用函数。
//中序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
//一旦visit()失败,则操作失败。
Status PostorderTraverse(BiTree T,Status(*Visit)(TElemType e));
//采用二叉链表存储结构,visit是对结点操作的应用函数。
//后序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
//一旦visit()失败,则操作失败。
Status LevelIOrderTraverse(BiTree T,Status(*Visit)(TElemType e));
//采用二又链表存储结构,Visit是对结点操作的应用函数。
//层序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
//一旦visit()失败,则操作失败
sqstack *InitStack()//初始化堆栈
{sqstack *s;
s->base=(SElemType*)malloc(100*sizeof(SElemType));
if(!s->base) return NULL;
s->top=s->base;
s->stacksize=100;
return s;
}
int StackEmpty(sqstack *s) //栈空判别
{return(s->top==s->base);
}
void Pop(sqstack *s,SElemType &e)//弹栈
{
e=*--s->top;
}
Status GetTop(sqstack *s,SElemType &e)
{
if(s->top==s->base) return ERROR;
e=*(s->top-1);
return OK;
}
void Push(sqstack *s,SElemType e)//将元素压入堆栈
{SElemType t;
*s->top++=e;
}
Status CreateBiTree(BiTree &T){
//按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树。
//构造二叉链表表示的二叉树T.
char ch;
ch=getche();
if(ch==' ') T=NULL;
else{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) return(OVERFLOW);
T->data=ch; //生成根结点
CreateBiTree(T->lchild);//构造左子树
CreateBiTree(T->rchild);//构造右子树
}
return OK;
}//CreateBiTree
Status PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
//采用二叉链表存储结构,visit是对数据元素操作的应用函数,
//先序遍历二叉树T的递归算法,对每个数据元素调用函数visit。
//调用实例: PreOrderTraverse(T,printElement);
{
if(T){
if (Visit(T->data))
if (PreOrderTraverse(T->lchild,Visit))
if (PreOrderTraverse(T->rchild,Visit)) return OK;
return ERROR;
}else return OK;
}//preOrderTraVerse
Status InOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
//采用二叉链表存储结构,visit是对数据元素操作的应用函数,
//中序遍历二叉树T的递归算法,对每个数据元素调用函数visit。
{
if(T){
if (InOrderTraverse(T->lchild,Visit))
if (Visit(T->data))
if (InOrderTraverse(T->rchild,Visit)) return OK;
return ERROR;
}else return OK;
}//preOrderTraVerse
Status PostOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
//采用二叉链表存储结构,visit是对数据元素操作的应用函数,
//后序遍历二叉树T的递归算法,对每个数据元素调用函数visit。
{
if(T){
if (PostOrderTraverse(T->lchild,Visit))
if (PostOrderTraverse(T->rchild,Visit))
if (Visit(T->data)) return OK;
return ERROR;
}else return OK;
}//preOrderTraVerse
Status PrintElement(TElemType e)
{ //输出元素e的值
printf("%c",e);
return OK;
}
Status InorderTraverseNoRecursion1(BiTree T,Status(*Visit)(TElemType e))
//采用二叉链表存储结构,visit是对数据元素操作的应用函数。
//中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit。
{sqstack *s;
BiTree p;
s=InitStack();p=T;
while(p||!StackEmpty(s))
{
if(p){ Push(s,p);p=p->lchild;}//根指针进栈,遍历左子树
else{ //根指针退栈,访问根结点,遍历右子树
Pop(s,p);if(!Visit(p->data)) return ERROR;
p=p->rchild;
}//else
}//while
return OK;
}//InorderTraVerse1
Status InorderTraverseNoRecursion2(BiTree T,Status(*Visit)(TElemType e))
//采用二叉链表存储结构,visit是对数据元素操作的应用函数。
//中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit。
{sqstack *s;
BiTree p;
s=InitStack();Push(s,T);
while(!StackEmpty(s))
{
while(GetTop(s,p)&&p) Push(s,p->lchild);//向左走到尽头
Pop(s,p); //空指针退栈
if(!StackEmpty(s)) { //访问结点,向右一步
Pop(s,p);if(!Visit(p->data)) return ERROR;
Push(s,p->rchild);
}//if
}//while
return OK;
}//InorderTraVerse1
void main()
{
BiTree t;
printf("\n请按先序遍历输入二叉树(当左右子树为空时用空格输入)\n");
CreateBiTree(t);
printf("\n该二叉树的先序遍历为:\n");
PreOrderTraverse(t,PrintElement);
printf("\n该二叉树的中序遍历为:\n");
InOrderTraverse(t,PrintElement);
printf("\n该二叉树的后序遍历为:\n");
PostOrderTraverse(t,PrintElement);
printf("\n该二叉树的中序遍历为:(用非递归调用1)\n");
InorderTraverseNoRecursion1(t,PrintElement);
printf("\n该二叉树的中序遍历为:(用非递归调用2)\n");
InorderTraverseNoRecursion2(t,PrintElement);
}