C:二叉树先序中序后序(递归,非递归)层序遍历算法严蔚敏版[新手向]⑦
近段时间本人在复习数据结构,重新敲一次代码,有什么不足的地方望大佬多多指教,严蔚敏版教程配套算法代码
#include<stdio.h>
#include<stdlib.h>
#define MAX_TREE_SIZE 100//二叉树的最大结点
#define STACK_INIT_SIZE 100//栈的初始空间
#define STACKNCREMRNT 10//栈的增加量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef char TElemType;
typedef int QElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;
typedef struct {
BiTree *base;//在构造栈前和销毁栈后,base的值为NULL
BiTree *top;//栈顶指针
int stacksize;//当前分配的元素空间以元素为单位
} SqStack;
typedef struct QNode {
BiTree data;
struct QNode *next;
} QNode,*QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
} LinkQueue;
//构造空栈
Status InitStack(SqStack &S) {
S.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTree));
if(!S.base)exit(OVERFLOW);//储存分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
//判断是否栈空
Status StackEmpty(SqStack S) {
if(S.top==S.base)return TRUE;
else return FALSE;
}
//若栈不空,用e返回S的栈顶元素
BiTree GetTop(SqStack S) {
BiTree e;
if(S.top==S.base)return ERROR;
e=*(S.top-1);
return e;
}
//为栈插入新的栈顶元素e
Status Push(SqStack &S,BiTree e) {
if(S.top-S.base>S.stacksize) {
S.base=(BiTree *)realloc(S.base,(S.stacksize+STACKNCREMRNT)*sizeof(BiTree));
if(!S.base)exit(OVERFLOW);//储存分配失败
S.top=S.base+S.stacksize;
}
*S.top++=e;
return OK;
}
//若栈不空,则删除栈顶元素,用e返回其值,返回OK,否则返回ERROR
Status Pop(SqStack &S,BiTree e) {
if(S.top==S.base)return ERROR;
e=*--S.top;
return OK;
}
//构造一个空队列
Status InitQueue(LinkQueue &Q) {
Q.front=Q.rear=(QueuePtr)malloc(sizeof(BiTree));
if(!Q.front)exit(OVERFLOW);//储存分配失败
Q.front->next=NULL;
return OK;
}
//插入元素e为Q的新队列
Status EnQueue(LinkQueue &Q,BiTree e) {
QueuePtr p;
p=(QueuePtr)malloc(sizeof(BiTree));
if(!p)exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
//若队列头不空,删除Q的队头元素
Status DeQueue(LinkQueue &Q,BiTree &e) {
QueuePtr p;
if(Q.front==Q.rear)return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
return OK;
}
//按照先序次序输入二叉树结点的值(一个字符),空格表示空树,构造二叉链表标识的二叉树T
Status CreateBiTree(BiTree &T) {
char ch;
scanf("%c",&ch);
if(ch == '#') T = NULL;
else {
T=(BiTNode *)malloc(sizeof(BiTNode));
if(!T) exit(OVERFLOW);
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
//判断是否队列为空
Status QueueEmpty(LinkQueue Q){
if(Q.front==Q.rear)return TRUE;
else return FALSE;
}
Status visit(TElemType e) {
printf("%c",e);
return OK;
}
//先序递归
Status PreTraverse(BiTree T,Status(*visit)(TElemType)) {
if(T) {
visit(T->data);
if(PreTraverse(T->lchild,visit))
if(PreTraverse(T->rchild,visit)) return OK;
return ERROR;
} else return OK;
}
//先序非递归
Status _PreTraverse(BiTree T,Status(*visit)(TElemType)) {
SqStack S;
BiTree p=T;
InitStack(S);
while(p||!StackEmpty(S)) {
if(p) { //向左走到尽头
Push(S,p);//进栈
visit(p->data);
p=p->lchild;
} else {
Pop(S,p);
p=*(S.top);
p=p->rchild;
}
}
return OK;
}
//中序递归
Status InTraverse(BiTree T,Status(*visit)(TElemType)) {
SqStack S;
BiTree p=T;
InitStack(S);
Push(S,T);//根指针进栈
while(!StackEmpty(S)) {
while(GetTop(S)&&p) {
p=*(S.top-1);
Push(S,p->lchild);
}//向左走到尽头
Pop(S,p);//空指针退栈
if(!StackEmpty(S)) {//访问结点,向右一步
Pop(S,p);
p=*(S.top);
visit(p->data);
Push(S,p->rchild);
}
}
return OK;
}
//中序非递归
Status _InTraverse(BiTree T,Status(*visit)(TElemType)) {
SqStack S;
InitStack(S);
BiTree p=T;
while(p||!StackEmpty(S)) {
if(p) { //根指针进栈,遍历左子树
Push(S,p);
p=p->lchild;
} else { //根指针退栈,访问根结点,遍历右子树
Pop(S,p);
p=*(S.top);
visit(p->data);
p=p->rchild;
}
}
return OK;
}
//后续递归
Status PostTraverse(BiTree T,Status(*visit)(TElemType)) {
if(T) {
if(PreTraverse(T->lchild,visit))
if(PreTraverse(T->rchild,visit)) {
visit(T->data);
return OK;
}
return ERROR;
} else return OK;
}
//层序遍历
void LevelTraverse(BiTree T,Status(*visit)(TElemType)) {
LinkQueue Q;
BiTree p=T;
if(T) {
InitQueue(Q);
EnQueue(Q,p);
while(!QueueEmpty(Q)) {
DeQueue(Q,p);
visit(p->data);
if(p->lchild!=NULL) EnQueue(Q,p->lchild);
if(p->rchild!=NULL) EnQueue(Q,p->rchild);
}
}
}
//ABC##DE#G##F###
int main() {
BiTree T;
CreateBiTree(T);
printf("\n");
PreTraverse(T,visit);
printf("\n");
// _PreTraverse(T,visit);
// printf("\n");
// InTraverse(T,visit);
// printf("\n");
// _InTraverse(T,visit);
// printf("\n");
// PostTraverse(T,visit);
// printf("\n");
// _PostTraverse(T,visit);
LevelTraverse(T,visit);
printf("\n");
}