数据结构(二叉树的遍历)

代码及运行结果分析

(包括先序,中序,后序遍历,以 及先序的非递归调用)相关代码如下:
#include<stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100 //宏定义 栈区的容量
#define STACKINCREMENT 10 //当容量不充足的时候增加的容量大小
#define MAX_TREE_SIZE 100//二叉树的最大结点数
#define ERROR 0
#define OK 1
typedef int elemtype;//定义结点值
typedef int Status;//返回值状态
typedef struct BiTNode{
elemtype data;
BiTNode *lchild,*rchild; /左右孩子指针/
}BiTNode,*BiTree;

//声明栈的数据结构
typedef BiTree SElemType;
typedef struct {
SElemType *top; //栈顶
SElemType *base; //栈底
int stacksize; //栈的容量

} SqStack;
//初始化栈
Status InitStack(SqStack S) {
S->base=(SElemType )malloc(STACK_INIT_SIZEsizeof(SqStack));
if(!S->base)
{
return ERROR;//分配栈空间失败则返回错误
}
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;//增加栈容量
return OK;
}
//进栈
Status Push(SqStack S,SElemType e) {
//判断栈区内存是否充足
if(S->top-S->base >= S->stacksize) {
//增加内存空间
S->base = (SElemType
)realloc(S->base,sizeof(SqStack));
if(!S->base) {
printf(“增加内存失败\n”);
return ERROR;
}
//top重新指向栈顶
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
S->top++ = e;
return OK;
}
//出栈
Status Pop(SqStack S,SElemType e) {
//没有元素返回错误
if(S->top == S->base) {
return ERROR;
}
//把栈顶的值返回并把指向栈顶的指针下移
e = –S->top;
return OK;
}
Status getTop(SqStack S,SElemType e) {
//栈中没有元素
if(S.top == S.base) {
printf(“栈中无元素\n”);
return ERROR;
}
e = (S.top - 1);
return OK;
}
//判断栈是否为空
Status StackEmpty(SqStack S) {
if(S.top == S.base) {
return OK;
} else {
return ERROR;
}
}
/
CreateBiTree
/
Status CreateBiTree(BiTree &T) {
/按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,
构造二叉链表表示的二叉树T。
/
elemtype ch;
scanf("%d",&ch);
if (ch==0)
{
T = NULL;
}
else {
if(!(T = (BiTNode )malloc(sizeof(BiTNode))))
return ERROR;
T->data = ch; /
生成根结点
/
CreateBiTree(T->lchild); /
构造左子树
/
CreateBiTree(T->rchild); /
构造右子树
/
}
return OK;
}
/采用二叉链表存储结构,Visit是对数据元素操作的应用函数,
先序遍历二叉树T的递归算法,对每个数据元素调用函数Visit。
最简单的Visit函数是:
/
Status visit(elemtype e) { // 输出元素e的值
printf("%3d",e); // 实用时,加上格式串
return OK;
}
// 调用实例:PreOrderTraverse(T, PrintElement);
/
//先序递归调用,调用函数本身(效率较低)
Status PreOrderTraverse( BiTree T )
{
if(T) {//存在二叉树
visit(T->data);//遍历根节点
PreOrderTraverse(T->lchild);//遍历左孩子
PreOrderTraverse(T->rchild);//遍历右孩子
}
} /
PreOrderTraverse*/
Status NRPreOrder(BiTree bt)
{/非递归先序遍历二叉树,用栈来做储存结构/
BiTree p = bt;//将树赋值给一个临时变量p
SqStack S;
InitStack(&S);//初始化栈
//当树的结点不为空或者栈不为空时执行循环遍历
while(p||!StackEmpty(S))
{
if§//当此结点不为空继续执行条件语句
{
visit(p->data);//p结点不为空输出p结点的数据域
Push(&S,p);//继续进栈
p = p->lchild;//遍历左孩子
}else
{
//否则父节点出栈,p指向父节点的右子树
Pop(&S,&p);
p = p->rchild;
}
}
}
//中序遍历 通过辅助存储结构 栈
Status InOrderTraverse(BiTree T) {
//先声明一个栈
SqStack S;
BiTree p;
//初始化栈
InitStack(&S);
//根指针进栈
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);
}
}
}
//后序遍历
Status postOrderTraverse(BiTree T) {

if(T==NULL) {
	return ERROR;;
}
postOrderTraverse(T->lchild);
postOrderTraverse(T->rchild);
visit(T->data);

}
int main()
{
BiTree T;
printf(“构件二叉树输入0表示当前分支结束:\n”);
CreateBiTree(T);
printf(“先序遍历递归调用后为:\n”);
PreOrderTraverse( T );
getchar();
printf("\n先序遍历非递归调用后为:\n");
NRPreOrder(T);
printf("\n中序遍历后为:\n");
InOrderTraverse(T);
printf("\n后序遍历后为:\n");
postOrderTraverse(T);
getchar();
}

运行后结果是:

0表示
结果所遍历的二叉树是:
在这里插入图片描述
先序遍历是:“根,左,右”
中序遍历是:“左,根,右”
后序遍历是:“左,右,根”
先序非递归采用栈储存结构

猜你喜欢

转载自blog.csdn.net/WJI777/article/details/83999579