中序遍历二叉树,即是先遍历左子树,再访问根节点,最后遍历右子树,这个顺序对于每棵子树都是一样的,是访问子树的共性,故可依次顺序设置循环,逐一访问每个结点。对于每一个树的子树,均要完成此操作。故在开始遍历之时,应先找到最左边的结点,遍历应从此开始。访问完此结点,应逐一访问此结点的根结点和右子树。
1、先设一个栈s和一个指向树根的指针p,用p指指向结点的lchild并顺其而下直到p==NULL跳出循环,在这一过程中把每个节点入栈,则此时的p指向的是树的最左结点。
2、栈顶元素出栈以访问最左结点。(此步很重要,是为了实现按栈内元素的顺序后入先出访问结点访问最左结点的根结点。栈内元素逐一退栈即为中序遍历的元素顺序。)
3、访问最左结点的根结点。
4、由于将右子树理解为一个子树,对其的遍历也是采用中序遍历的方法,故将右子树的根结点理解为开始遍历树时的根结点,故可用语句p=p->rchild,则又开始了对一个树的遍历,p指针又会走遍右子树的每一个结点。
附中序非递归遍历二叉树算法,可以直接复制粘贴到VC++即可编译运行。考虑到只作为一个示范作用,未编写空间释放程序,请各位大侠高动贵手。小弟才疏学浅,在此现丑了。
此程序在VC++6.0下调试成功:
/*
* All rights reserved.
*
* 文件名称:Traverse.c
* 文件标识:为二叉树各种操作中的一种
* 摘 要:二叉树操作,包含先序、中序和后序遍历的递归算法,
* 及中序遍历的非递归算法。
*/
#include<stdlib.h>
#include<stdio.h>
#define STACK_INIT_SIZE 100//栈初始分配的空间数
#define STACKINCREAMENT 10//栈空间不够时增加的空间数
typedef char eletype;//二叉树结点信息类型
typedef struct BiTNode//二叉树结点类型
{
struct BiTNode *lchild,*rchild;
eletype data;
}BiTNode;
typedef BiTNode *elemtype;//elemtype声明为指针类型
typedef struct stack//栈的存储类型,采用动态分配
{
elemtype *base;
elemtype *top;
int stacksize;
}sqstack;
sqstack *initstack()//创建栈
{
sqstack *s;
if (!(s = (sqstack *)malloc(sizeof(sqstack))))exit(-1);
s->base = (elemtype *)malloc(STACK_INIT_SIZE*sizeof(elemtype));//初始化为栈分配STACK_INIT_SIZE个elemtype类型的空间
if (!s->base)//分配空间失败
{
exit(-2);
printf("栈空间分配失败!\n");
}
if (s->base)//分配空间成功
printf("栈空间分配成功!\n");
s->top = s->base;//初始化栈的头尾指针
s->stacksize = STACK_INIT_SIZE;
return s;
}
void push(sqstack *s,elemtype e)//压栈,e要是一个地址
{
if (s->top-s->base>=s->stacksize)//栈满
{
s->base = (elemtype *)realloc(s->base,(s->stacksize+STACKINCREAMENT)*sizeof(elemtype));//栈满时增加空间
if (!s->base)//增加分配空间失败
exit(-2);
s->stacksize += STACKINCREAMENT;
}
*(s->top) = e;
s->top++;
}
elemtype pop1(sqstack *s)//出栈1,返回的e为栈顶元素是一个地址
{
elemtype e;
if (s->top == s->base)return 0;//栈空时返回
s->top--;
e = *(s->top);
return e;
}
int stackempty(sqstack *s)//判断栈空,栈空返回1,否则返回0
{
if (s->base == s->top)return 1;
else return 0;
}
BiTNode *CreateBiTree()//先序递归法建树
{
char x;
BiTNode *t;
scanf("%c",&x);
if (x == ' ')t = NULL;
else
{
if (!(t = (BiTNode *)malloc(sizeof(BiTNode))))exit(-1);
t->data = x;//建立节点
t->lchild = CreateBiTree();//建左子树
t->rchild = CreateBiTree();//建右子树
}
return t;
}
int InOrder(BiTNode *t)//中序遍历二叉树非递归算法
{
sqstack *s;
BiTNode *p;
s = initstack();//初始化栈
p = t;
printf("中序遍历二叉树,字符序列为:\n");
while (p||!stackempty(s))
{
while (p)//找最左结点
{
push(s,p);
p = p->lchild;//p指针顺lchild而下
}
p = pop1(s);//栈顶元素出栈以访问最左结点
printf("%c",p->data);//访问最左结点
p = p->rchild;
}
printf("\n");
return 1;
}
void main()
{
BiTNode *t;
printf("请输入建树字符序列,以空格表示NULL:\n");
t = CreateBiTree();
InOrder(t);
}