#include"tree.cpp" //包含了二叉树的基本算法
//---------------------先序遍历---------------
/*根 --左 --右*/
void Preorder(BTNode *b){
if(b!=NULL){
printf("%c",b->data); //访问结点
Preorder(b->lchild); //递归遍历左子树
Preorder(b->rchild); // 递归遍历右子树
}
}
//-----非递归遍历算法
void Preorder1(BTNode *b){
BTNode *St[MaxSize],*p; //St[]为存储双亲结点的栈
int top = -1; //栈顶指针
if(b!=NULL){
top++;
St[top] = b; //根结点进栈
while(top>-1){ //栈空时结束循环
p=St[top]; //退栈并访问该节点
top--;
printf("%c",p->data); //访问结点
if(p->rchild != NULL){ //有右孩子,将其进栈
top++;
St[top] = p->rchild;
}
if(p->lchild != NULL ){ //有左孩子,将其进栈
top++;
St[top] = p->lchild;
} //右孩子先进栈,利用的是栈先进后出的原理
}
}
printf("\n");
}
//------------中序遍历--------------
//左 根 右
//递归遍历
void Inorder(BTNode *b){
if(b!=NULL){
Inorder(b->lchild);
printf("%c",b->data); //访问结点
Inorder(b->rchild); // 递归遍历右子树
}
}
//非递归遍历
void Inorder1(BTNode *b){
BTNode *St[MaxSize],*p;
int top=-1;
if(b != NULL){
p=b;
while(top>-1 || p!= NULL){
while(p!=NULL){ //扫描p结点下的所有左子树,并进栈 ,p也进栈
top++;
St[top] = p;
p = p->lchild;
}
//此时已经退出第二层循环
if(top>-1){
p=St[top]; //p结点出栈,并访问
top--;
printf("%c",p->data);
p = p->rchild; //p指向右孩子
}
}
printf("\n");
}
}
//--------------后序遍历 ---------
// 左---右---根
//递归遍历
void Postorder(BTNode *b){
if(b != NULL){
Postorder(b->lchild); //递归调用左子树
Postorder(b->rchild);
printf("%c",b->data); //访问根结点
}
}
//非递归遍历
void Postorder2(BTNode *b){
BTNode *St[MaxSize],*p;
int top=-1;
bool flag;
if(b!=NULL){
do{
while(b!=NULL){ //遍历b结点左子树
top++;
St[top] =b;
b = b->lchild;
}
p=NULL; //p指向当前结点的前一个已访问的结点
flag = true; //flag为真表示正在处理栈顶结点
while(top!=-1 && flag){
b = St[top]; //取出当前的栈顶元素
if(b->rchild==p){ //若右子树不存在或已被访问,则访问该结点
printf("%c",b->data); //访问b结点
top--;
p = b; //p指向被访问的结点
} else{
b=b->rchild; //b指向右子树
flag=false; //表示当前不是处理栈顶结点
}
}
}while(top!=-1);
printf("\n");
}
}
//层次遍历
/*
算法思想:
1、初始化一个辅助队列
2、根结点入队【存的是指针而不是结点本身,所以是 Qu[rear] = b;而不是 Qu[rear] = b->data;】
3、若队列非空,则队头结点出队,访问该结点,并将该结点的左右孩子插入队尾
4、重复,直到队列为空
*/
void TravLevel(BTNode *b){
BTNode *Qu[MaxSize]; //定义环形队列
int front,rear; //定义队首和队尾指针
front = rear =0; //初始化队列
// if(b!=NULL)
// printf("%c",b->data); //访问根结点
rear++;
Qu[rear] = b; //根结点进队
while(rear != front){ //队列不为空
front = (front + 1)%MaxSize; //队头结点出队,并访问该结点
b = Qu[front]; //front指向结点已出队
printf("%c",b->data);
if(b->lchild != NULL){ //若有左孩子,将左孩子入队
rear = (rear+1)%MaxSize;
Qu[rear] = b->lchild;
}
if(b->rchild != NULL){ //若有右孩子,将右孩子入队
rear = (rear+1)%MaxSize;
Qu[rear] = b->rchild;
}
}
printf("\n");
}
/*
方法二
1、初始化一个辅助队列
2、访问根结点,并入队【存的是指针而不是结点本身】
3、若队列非空,则队头结点出队,访问该结点的左右孩子,并将左右孩子插入队尾
4、重复,直到队列为空
*/
void TravLevel01(BTNode *b){
BTNode *Qu[MaxSize];
int front,rear;
front = rear = 0;
if(b!=NULL)
printf("%c",b->data);
rear++;
Qu[rear] = b;
while(rear != front){
front = (front+1)%MaxSize;
b = Qu[front];
if(b->lchild != NULL){
printf("%c",b->data);
rear = (rear+1)%MaxSize;
Qu[rear] = b->lchild;
}
if(b->rchild!=NULL){
printf("%c",b->data);
rear = (rear+1)%MaxSize;
Qu[rear] = b->rchild;
}
}
printf("\n");
}
int main(){
BTNode *b;
printf("创建二叉树\n");
CreatBTree(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))");
printf("输出二叉树"); DispBTree(b);printf("\n");
printf("层次遍历二叉树:\n");
printf("方法一:");
TravLevel(b);
printf("方法二:");
TravLevel01(b);
printf("-----先序遍历二叉树:\n");
printf("递归:");
Preorder(b);printf("\n");
printf("非递归:");
Preorder1(b);
printf("-----------中序遍历二叉树:\n");
printf("递归:");printf("\n");
Inorder(b);
printf("非递归:");
Inorder1(b);
printf("---------------------后序遍历二叉树:\n");
printf("递归:");printf("\n");
Postorder(b);
printf("非递归:");
Postorder2(b);
printf("释放二叉树\n");
DestroyBTree(b);
return 1;
}