内容:编写程序,实现下述功能,并上机调试通过。
- 按中序顺序建立一课二叉树;
- 用非递归的方式遍历二叉树(先序,中序或后序),输出遍历序列
本题有两个要求,首先,要用中序顺序建立二叉树。但问题在于,只用中序输入无法创建一个确定的二叉树,因为对于一个已知的中序遍历结果,由于根节点不确定性,所以可能会对应多种不同结构的二叉树,例子如下:
所以我们要想办法解决根节点不确定的问题,对此有两个方向的想法。
一是:在编译过程规定好根节点的标识符,当输入该字符时,直接将该字符定义为根节点,在遍历结果中,该字符左侧即为左子树成员,右侧即为右子树成员。最左侧元素即为一个叶子结点。由此可生成一个确定的二叉树。
二是:通过采用其他的结构(先序,后序,层序)与中序结果进行比对,通过对同一二叉树的不同遍历结果,找出根节点在中序遍历结果中的位置,该位置以左即为左子树,以右即为右子树。此报告以中序加后序为例进行演示。后序遍历的最后一个元素即为整个二叉树根节点,在通过递归的方法求左子树的根节点,以此类推,求完左子树的所有元素后,再同方法求右子树的所有元素,完成整个二叉树的创建。
问题的第二部分要求用非递归方法实现二叉树的先序遍历,首先,将生成的二叉树以二叉链表的形式存储,一维数组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;
}