数据结构总结8——树2——二叉树的非递归遍历 by DexterYan

一、基础知识

二、代码要求

利用二叉链表实现二叉树的存储,利用栈实现二叉树的中序非递归遍历算法,
利用队列实现二叉树的层序遍历(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、先举最简单的例子,调试再加功能。

猜你喜欢

转载自blog.csdn.net/qq_41259302/article/details/90523027
今日推荐