一、基础知识
二、代码要求
利用二叉链表实现二叉树的存储,利用栈实现二叉树的中序非递归遍历算法,
利用队列实现二叉树的层序遍历(2学时)。
三、代码实现
#include<stdio.h>
#include<stdlib.h>
#define N 100
#define MAXNODE 100
typedef struct node
{
char data;
struct node *lchild,*rchild;
}BTNode;
typedef struct stack//定义栈的类型
{
BTNode *datanode;
int flag;//用来检测第几次访问结点
}fstack;
BTNode *createbintree();
void InOrder(BTNode *bt);
void LevelOrder(BTNode *bt);
void visit(BTNode *bt);
void postorder(BTNode *bt);
int main()
{
BTNode *t;
printf("请按先序遍历输入树(#表示结点为空):\n");
t=createbintree();
printf("用栈中序非递归遍历输出:");
InOrder(t);
printf("\n用队列层序遍历输出:");
LevelOrder(t);
printf("\n用栈后序非递归遍历输出:");
postorder(t);
return 0;
}
/*---二叉树的建立---*/
BTNode *createbintree()
{
BTNode *t;
char x;
scanf("%c",&x);
if (x=='#')
t=NULL;
else
{
t=(BTNode *)malloc(sizeof(BTNode));
t->data=x;
t->lchild=createbintree();
t->rchild=createbintree();
}
return t;
}
/*中序遍历的非递归算法*/
void InOrder(BTNode *bt)
{
BTNode *s[MAXNODE],*p=bt;//定义栈
/*核心思想就是定义一个一维指针数组,并且指针类型为BTNode类型*/
int top=-1;
if(p==NULL)
return;
do{
while(p!=NULL)
{
if(top>=MAXNODE-1)
{
printf("栈溢出\n");
return;
}
s[++top]=p;
p=p->lchild;
}
if(top==-1)
return;
else
{
p=s[top--];
visit(p);
p=p->rchild;
}
}while(p!=NULL||top!=-1);
}
/*二叉树的队列层序遍历 */
void LevelOrder(BTNode *bt)
{
BTNode *Queue[MAXNODE];
int front,rear;
if(bt==NULL)
return;
front=-1;
rear=-1;
Queue[++rear]=bt;
while(front!=rear)
{
front++;
visit(Queue[front]);
if(Queue[front]->lchild!=NULL)
{
rear++;
Queue[rear]=Queue[front]->lchild;
}
if(Queue[front]->rchild!=NULL)
{
rear++;
Queue[rear]=Queue[front]->rchild;
}
}
}
/*访问结点函数*/
void visit(BTNode *bt)
{
printf("%c ",bt->data);
}
/*后序非递归遍历*/
void postorder(BTNode *bt)
{
fstack hs[MAXNODE];
BTNode *p=bt;
int top=-1;
do
{
while(p!=NULL)
{//左结点遍历入栈
hs[++top].datanode=p;
hs[top].flag=0;
p=p->lchild;
}
if(top>=0)//前提,栈里有东西,及所有左孩子处理完毕后
{
if(hs[top].flag==1)//如果flag为1,说明是从右子树返回的
{
p=hs[top].datanode;
visit(p);//访问该结点
top--;
p=NULL;
}
else//当前结点的右孩子还未访问
{
p=hs[top].datanode;//得到栈顶结点
p=p->rchild;//访问右孩子
hs[top].flag=1;//标志左右孩子被访问过了
}
}
}while(p!=NULL||top!=-1);//栈不空或者p不空
}
/*void postorder(BTNode *bt)//写的第一个版本
{
fstack *hs[MAXNODE];
BTNode *p=bt;
int top=-1;
do
{
while(p!=NULL)
{
hs[++top]->datanode=p;//入栈
hs[top]->flag=0;
p=p->lchild;
}
p=hs[top]->datanode->rchild;
hs[top]->flag++;
if(hs[top]->datanode->rchild==NULL)
{
visit(hs[top]->datanode);
hs[top]->datanode=NULL;
top--;
p=hs[top]->datanode->rchild;
}
else
{
hs[++top]->datanode=p;
}
if(top==-1)
return;
}while(p!=NULL||top!=-1);
}*/
四、代码反思总结
总结:
1、函数在前边没有定义函数头文件那种形式出了warning,是不是和函数的排列顺序有关?
2、写出后序非递归遍历,自己思考怎么在栈的数据中劈开加入一个flag量,以及怎么修改被影响的量
2的总结还有考虑过程:栈本身是一个一维数组,树的栈是把栈定义为一个一维指针数组,将入栈的指向结点
达到访问效果,因此定义一个结构体,然后定义结构体指针一维数组,再了解定义结构体的方式,
3、先举最简单的例子,调试再加功能。