关于中序创建二叉树

内容:编写程序,实现下述功能,并上机调试通过。

  1. 按中序顺序建立一课二叉树;
  2. 用非递归的方式遍历二叉树(先序,中序或后序),输出遍历序列

 本题有两个要求,首先,要用中序顺序建立二叉树。但问题在于,只用中序输入无法创建一个确定的二叉树,因为对于一个已知的中序遍历结果,由于根节点不确定性,所以可能会对应多种不同结构的二叉树,例子如下:

 

所以我们要想办法解决根节点不确定的问题,对此有两个方向的想法。

一是:在编译过程规定好根节点的标识符,当输入该字符时,直接将该字符定义为根节点,在遍历结果中,该字符左侧即为左子树成员,右侧即为右子树成员。最左侧元素即为一个叶子结点。由此可生成一个确定的二叉树。

二是:通过采用其他的结构(先序,后序,层序)与中序结果进行比对,通过对同一二叉树的不同遍历结果,找出根节点在中序遍历结果中的位置,该位置以左即为左子树,以右即为右子树。此报告以中序加后序为例进行演示。后序遍历的最后一个元素即为整个二叉树根节点,在通过递归的方法求左子树的根节点,以此类推,求完左子树的所有元素后,再同方法求右子树的所有元素,完成整个二叉树的创建。

问题的第二部分要求用非递归方法实现二叉树的先序遍历,首先,将生成的二叉树以二叉链表的形式存储,一维数组stack[MAXNODE]用以实现栈,设置变量top用以表示栈顶位置,通过top值的变化实现栈的遍历,即二叉树的遍历。

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

#define MAXNODE 100
typedef char TElemType;
typedef int Status;
typedef struct BiTNode
{
	TElemType data;
	struct BiTNode*lchild, *rchild;
}BiTNode, *BiTree;

//中序后序建立二叉树
BiTNode *Creat(int len, char *zhong, char *hou)
{
	if (len == 0)//长度为0,返回错误
	{
		return NULL;
	}
	//创建根节点
	BiTNode *T;
	T = (struct BiTNode *)malloc(sizeof(struct BiTNode));
	//由后续遍历二叉树得,后序的第一个元素即为根节点
	T->data = hou[len - 1];
	int i;
	for (i = 0; i < len; i++)
	if (hou[len - 1] == zhong[i])
		break;
	//for循环找出中序的根节点在数组中的位置
	//构造左子树
	T->lchild = Creat(i, zhong, hou);//通过递归找左子树的根节点,结束后i的值为左子树中节点的个数
	//构造右子树
	T->rchild = Creat(len - i - 1, zhong + i + 1, hou + i);//通过递归找右子树的根节点
	//zhong+i为根节点的地址值
	return T;
}

//访问根节点
void visite(char ch)
{
	printf("%c", ch);
}

//非递归先序遍历
void NRPreOrder(BiTree T)
{
	BiTree stack[MAXNODE], p;
	int top;
	if (T == NULL)return;
	top = 0;
	p = T;
	while (!(p == NULL&&top == 0))
	{
		while (p != NULL)
		{
			visite(p->data);
			if (top<MAXNODE - 1)
			{
				stack[top] = p;
				top++;
			}
			else
			{
				printf("栈溢出");
				return;
			}
			p = p->lchild;
		}
		if (top <= 0)return;
		else
		{
			top--;
			p = stack[top];
			p = p->rchild;
		}
	}
}

int main()
{
	char zhong[100], hou[100];
	int len;
	printf("中序二叉树:\n");
	scanf("%s", zhong);
	printf("后序二叉树:\n");
	scanf("%s", hou);
	BiTNode *T = NULL;
	len = strlen(zhong);
	T = Creat(len, zhong, hou);
	printf("先序遍历:\n");
	NRPreOrder(T);
	return 0;
}

 

  • 12
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值