遍历二叉树--先序输入 中序后序层序输出

一、需求分析

1、遍历二叉树。
请输入一棵二叉树的扩展的前序序列,经过处理后生成一棵二叉树,然后对于该二叉树输出中序和后序遍历序列。

2、按层次遍历二叉树。


二、概要设计

  1. 程序中用到的抽象数据类型的定义:
typedef struct BiTNode
{	//二叉树结点结构定义
	char data;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
  1. 主程序的流程:
    首先用fgets函数得到先序遍历序列,存入数组。用e指针指向数组首尾地址,使用CreateBiTree()函数建立二叉树,用root表示二叉树根结点。
    其次建立中序输出函数InorderTraversal()和后序输出函数PostorderTraversal(),以及层序输出函数LevelorderBiTree(),依次输出结果。
    最后使用DestroyBiTree()释放空间。
int main()
{
	char PreOrder[MAXSIZE+1];
	fgets(PreOrder, MAXSIZE, stdin);
	char *e = PreOrder;
	BiTree root = CreateBiTree(&e);
	
	printf("中序遍历结果:");
	InorderTraversal(root); 
	printf("\n");
	
	printf("后序遍历结果:");
	PostorderTraversal(root); 
	printf("\n");

	printf("层序遍历结果:");
	LevelorderBiTree(root);
	printf("\n");
	
	//释放空间
	DestroyBiTree(root);
	
	return 0; 
}

三、详细设计

  1. 通过先序序列创建二叉树。
    采用递归。
    当e所指数组元素为“#”或者数组遍历结束,返回NULL,即空结点。
    当e指向其他元素,创建新结点root,e移动到数组下一位,再递归构造root的左子树,和右子树。返回根结点。
BiTree CreateBiTree(char **e)
{
	if(**e == '#' || **e == '\0')
	{
		(*e)++;
		return NULL;
	}
	BiTree root;
	root = CreateNode(**e);
	(*e)++;
	root->lchild = CreateBiTree(e);	//递归构造左子树 
	root->rchild = CreateBiTree(e); 	//递归构造右子树 
	return root;
}
  1. 中序、后序遍历输出
    中序、后序遍历函数思路相同,均是采用递归思想,不同之处在于,中序输出顺序为“左根右”,即先输出左子树,再输出根结点,最后输出右子树。后序输出顺序则是“左右根”。
//中序遍历
void InorderTraversal(BiTree root)
{
	if(root == NULL) 	return;
	InorderTraversal(root->lchild);
	printf("%c", root->data);
	InorderTraversal(root->rchild);
}

//后序遍历
void PostorderTraversal(BiTree root)
{
	if(root == NULL) return;
	PostorderTraversal(root->lchild);
	PostorderTraversal(root->rchild);
	printf("%c", root->data);
}
  1. 层序遍历输出
    层序遍历采用队列储存二叉树结点,先是第一层根结点入队,其次第二层从左到右,根结点的左右子树入队。
    用head记录当前队列对头,在输出队头元素时,再将该队头元素的左右子树入队。
//层序遍历
void LevelorderBiTree(BiTree root)
{
	if(root == NULL)	return;
	
	BiTree queue[1000]; //用队列储存二叉树每层
	int head = 0, tail = 0;	//队列的头尾 
	BiTree p;
	 
	queue[tail++] = root; //根结点入队
	while(head != tail) 
	{	//队列不空
		p = queue[head++];
		printf("%c", p->data);
		if(p->lchild) queue[tail++] = p->lchild;
		if(p->rchild) queue[tail++] = p->rchild;
	}
}

四、调试分析

写代码时问题出现在建立二叉树上,我用数组存储先序输入序列,一开始想直接用PreOrder即数组首地址放入,即CreateBiTree(PreOrder),但由于数组首地址不可以更改,所以建立失败。解决方法:再建立一个指针指向数组。

int main()
{
	char PreOrder[MAXSIZE+1];
	fgets(PreOrder, MAXSIZE, stdin);
	char *e = PreOrder;
	BiTree root = CreateBiTree(&e);
	//其他代码...
}

五、测试结果

输入:ABDG##HJ####CE#I##F##
输出:
在这里插入图片描述


附录

6、附录:带注释的源程序。

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 100

typedef struct BiTNode
{	//二叉树结点结构定义
	char data;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

//创建新结点 
BiTree CreateNode(char data)
{
	BiTree node = (BiTree)malloc(sizeof(BiTNode));
	node->data = data;
	node->lchild = NULL;
	node->rchild = NULL;
	return node;
}

//通过先序序列创建二叉树 
BiTree CreateBiTree(char **e)
{
	if(**e == '#' || **e == '\0')
	{
		(*e)++;
		return NULL;
	}
	BiTree root;
	root = CreateNode(**e);
	(*e)++;
	root->lchild = CreateBiTree(e);	//递归构造左子树 
	root->rchild = CreateBiTree(e); 	//递归构造右子树 
	return root;
}

//中序遍历
void InorderTraversal(BiTree root)
{
	if(root == NULL) 	return;
	InorderTraversal(root->lchild);
	printf("%c", root->data);
	InorderTraversal(root->rchild);
}

//后序遍历
void PostorderTraversal(BiTree root)
{
	if(root == NULL) return;
	PostorderTraversal(root->lchild);
	PostorderTraversal(root->rchild);
	printf("%c", root->data);
}

//层序遍历
void LevelorderBiTree(BiTree root)
{
	if(root == NULL)	return;
	
	BiTree queue[1000]; //用队列储存二叉树每层
	int head = 0, tail = 0;	//队列的头尾 
	BiTree p;
	 
	queue[tail++] = root; //根结点入队
	while(head != tail) 
	{	//队列不空
		p = queue[head++];
		printf("%c", p->data);
		if(p->lchild) queue[tail++] = p->lchild;
		if(p->rchild) queue[tail++] = p->rchild;
	}
}

//释放二叉树
void DestroyBiTree(BiTree root)
{
	if(root == NULL) return;
	DestroyBiTree(root->lchild);
	DestroyBiTree(root->rchild);
	free(root);
}

int main()
{
	char PreOrder[MAXSIZE+1];
	fgets(PreOrder, MAXSIZE, stdin);
	char *e = PreOrder;
	BiTree root = CreateBiTree(&e);
	
	printf("中序遍历结果:");
	InorderTraversal(root); 
	printf("\n");
	
	printf("后序遍历结果:");
	PostorderTraversal(root); 
	printf("\n");

	printf("层序遍历结果:");
	LevelorderBiTree(root);
	printf("\n");
	
	//释放空间
	DestroyBiTree(root);
	
	return 0; 
}

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值