题目内容
编写程序,实现以下功能:
- 按中序顺序建立一棵二叉树。
- 用先序非递归方式遍历二叉树。
算法设计
二叉树的创建可以是先序创建、先序中序创建、中序后序创建。显然不可以只用中序或者后序单独创建一棵二叉树。根据定义,二叉树的先序遍历是先访问根结点,再按照先序遍历方式遍历根结点的左子树,最后按照先序遍历方式遍历根结点的右子树。这就是说,再先序序列中,第一个结点一定是二叉树的根结点,另一方面,中序遍历是先遍历左子树,然后访问根结点,最后再遍历右子树,这样,根结点在中序序列中必然将中序序列分割成两个子序列,根据两个子序列在在先序序列中找到左子序列和右子序列。在先序序列中,左子序列的第一个结点就是左子树的根结点,右子序列的第一个结点就是右子树的根结点,这样,就确定了二叉树的三个结点。同时,左子树和右子树的根结点又可以把左子序列和右子序列划分成两个子序列,如此递归下去,当取尽先序序列中的结点时,便可以得到一棵二叉树,即可以完成先序中序创建一颗二叉树。
具体思路:
- 我们知道先序序列的第一个结点为根结点;
- 通过Pos()函数找到传入根结点的值,找到在中序序列中对用的位置pos;
- 再根据这个位置pos,递归创建左子树和右子树;
- 采用二叉链表做存储结构,建立二叉树;
- 借助于栈结构来实现二叉树遍历的非递归算法。
- 概要设计
该算法设计了四个函数:
函数Pos():用来寻找根结点位置,在中序中查找对应的位置。
函数MinCreate():用来先序中序创建二叉树。
函数NRPreOrder():用来非递归先序遍历二叉树。
主函数main()
源代码
/********
date:2021-11-12
author:sy
version:1.0
Description:用先序和中序创建二叉树,用先序非递归方法遍历二叉树
************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<bits/stdc++.h>
#define MAXNODE 100
#define SIZE 50
using namespace std;
typedef char TElemType;
/*定义二叉树的结构类型*/
typedef struct BINode{
TElemType data;
struct BINode *lchild;
struct BINode *rchild;
}BINode,*BITree;
/*找根结点位置*/
int Pos(TElemType *min,TElemType val,int n)
{
if(min == NULL) return -1;
int pos = -1;
for(int i=0;i<n;i++)
{
if(min[i] == val)
{
pos = i;
}
}
return pos;
}
/*中序创建二叉树*/
BITree MinCreate( BITree &root, TElemType *pre,TElemType *min,int n)
{
if(pre == NULL || min == NULL || n==0)
{
return NULL;
}
if(n>0)
{
root = (BITree)malloc(sizeof(BINode));
root->data = pre[0];
root->lchild = NULL;
root->rchild = NULL;
int pos = Pos(min,root->data,n);
if(pos == -1)
{
printf("二叉树创建失败!");
exit(1);
}
root->lchild = MinCreate(root->lchild,pre+1,min,pos); /*递归调用自身进行构造左右子树*/
root->rchild = MinCreate(root->rchild,pre+pos+1,min+pos+1,n-pos-1);
}
return root;
}
/*非递归方法(先序)遍历二叉树*/
void NRPreOrder(BITree bt)
{
BITree stack[MAXNODE],p;
int top;
if(bt==NULL) return;
top=0;
p=bt;
while(!(p==NULL&&top==0))
{
while(p!=NULL)
{
cout<<p->data<<" "; //访问结点的数据域
if(top<=MAXNODE-1)
{
stack[top]=p;
top++;
}
else
{
printf("栈溢出");
return;
}
p=p->lchild; //指针指向p的左孩子
}
if(top<=0) return; //栈空时结束
else
{
top--;
p=stack[top]; //从栈中弹出栈顶元素
p=p->rchild; //指针指向p的右孩子结点
}
}
}
int main()
{
char pre[SIZE];
char min[SIZE];
int n;
BITree bt = NULL;
printf("\n 先序输入二叉树: \n");
gets(pre);
printf("\n 中序输入二叉树: \n");
gets(min);
n = strlen(pre);
MinCreate(bt,pre,min,n);
printf("\n 非递归先序遍历二叉树: \n");
NRPreOrder(bt);
return 0;
}
测试
由先序和中序创建二叉树,分别输入先序二叉树和中序二叉树,由此来创建一颗完整的二叉树。
二叉树构建如右图:
运行结果如下: