首先明确先序遍历的顺序为:根结点→左结点→右结点;中序遍历的顺序为:左结点→根结点→右结点;后序遍历的顺序为:左结点→右结点→根结点。
1. 给定先序和中序建立二叉树。
1) 函数原型:
void CreateByPreAndIn(BinaryTree &T,charpreorder[],char inorder[],int first,int last)
2) 参数说明:
T是当前要建立的二叉树结点;
preorder是先序遍历的数组;inorder是中序遍历的数组;
first是以T为根结点的树中所有元素在inorder数组的最左下标,last是最右下标
3) 算法描述:
由于二叉树是递归定义的,遍历也是递归进行的,因此,递归建树比较方便。
假设当前要建立的二叉树的根结点在preorder中的下标为index(对整棵树而言index=0),当前要建立的二叉树在inorder中的范围为[first,last](对整棵树而言,自然就是[0,strlen(inorder)-1]),当前根结点在inorder中的下标为loc。
对当前要建立的二叉树结点T(当前树的根结点):
若first>last:该结点不存在,即T=NULL;
若first==last:该结点存在,分配内存,T->data=preorder[index],但是该结点没有左右子结点,即T->leftchild=T->rightchild=NULL,继续向下建立下一个结点,即index++;
若firstdata=preorder[index],index++后,由于先序遍历的顺序为:根结点→左结点→右结点,所以下一个首先建立左子结点(相对于结点T而言),然后建立右子结点。由于中序遍历的顺序为:左结点→根结点→右结点,所以inorder中的[first,loc-1]均为T的左子树结点,[loc+1,last]均为T的右子树节点,所以调用 CreateByPreAndIn(T->leftchild,preorder,inorder,first,loc-1)和 CreateByPreAndIn(T->rightchild,preorder,inorder,loc+1,last)建立T的左右子树。
2. 给定后序和中序建立二叉树。
1) 函数原型:
voidCreateByPostAndIn(BinaryTree &T,char postorder[],char inorder[],intfirst,int last)
2) 参数说明:
postorder是先序遍历的数组,其余同上。
3) 算法描述:
基本同上,区别在于上个算法中index从0加到strlen(preorder)-1,当first
3. 注意:给定前序和后序无法求出唯一的二叉树。
举例如下:
树A:有结点1,2,3,2是1的左孩子,3是2的右孩子
树B:有结点1,2,3,2是1的右孩子,3是2的左孩子
则A,B的前序都是123,后序都是321,但A的中序是231,B的中序是132.
/* 数据结构分析与学习专栏
* Copyright (c) 2015, 山东大学 计算机科学与技术专业 学生
* All rights reserved.
* 作 者: 高祥
* 完成日期: 2015 年 4 月 12 日
* 版 本 号:017
*任务描述
* 1:给定先序和中序建立二叉树 ;
* 2:给定后序和中序建立二叉树 ;
*主要函数:
* 1.void CreateByPreAndIn(BinaryTree &T,char preorder[],char inorder[],int first,int last);//给定先序和中序建立二叉树
* 2.void CreateByPostAndIn(BinaryTree &T,char postorder[],char inorder[],int first,int last);//给定后序和中序建立二叉树
* 3.void PreOrderTraverse(BinaryTree T);//前序遍历输出二叉树
* 4.void InOrderTraverse(BinaryTree T);//中序遍历输出二叉树
* 5.void PostOrderTraverse(BinaryTree T);//后序遍历输出二叉树
* 6.void print(BinaryTree T);//打印二叉树
*/
#include
#include
using namespace std;
typedef struct BTNode//二叉树结点类型
{
char data;
struct BTNode *leftchild;
struct BTNode *rightchild;
} BTNode,*BinaryTree;
int index;
void CreateByPreAndIn(BinaryTree &T,char preorder[],char inorder[],int first,int last);//给定先序和中序建立二叉树
void CreateByPostAndIn(BinaryTree &T,char postorder[],char inorder[],int first,int last);//给定后序和中序建立二叉树
void PreOrderTraverse(BinaryTree T);//前序遍历输出二叉树
void InOrderTraverse(BinaryTree T);//中序遍历输出二叉树
void PostOrderTraverse(BinaryTree T);//后序遍历输出二叉树
void print(BinaryTree T);//打印二叉树
int main()
{
cout<<"第一组测试数据:\n";
char preorder[]= {'A','B','C','D','E','G','F'};
char inorder[]= {'C','B','E','G','D','F','A'};
char postorder[]= {'C','G','E','F','D','B','A'};
BinaryTree T1;
index=0;
cout<<"\n由先序和中序建立二叉树:\n";
CreateByPreAndIn(T1,preorder,inorder,0,6);
print(T1);
BinaryTree T2;
index=6;
cout<<"\n由后序和中序建立二叉树:\n";
CreateByPostAndIn(T2,postorder,inorder,0,6);
print(T2);
cout<<"\n\n第二组测试数据:\n";
char preorder2[]= {'A','B','D','E','F','G','C','H','J','I','K'};
char inorder2[]= {'D','B','F','G','E','A','H','J','C','I','K'};
char postorder2[]= {'D','G','F','E','B','J','H','K','I','C','A'};
BinaryTree T3;
index=0;
cout<<"\n由先序和中序建立二叉树:\n";
CreateByPreAndIn(T3,preorder2,inorder2,0,10);
print(T3);
BinaryTree T4;
index=10;
cout<<"\n由后序和中序建立二叉树:\n";
CreateByPostAndIn(T4,postorder2,inorder2,0,10);
print(T4);
return 0;
}
void CreateByPreAndIn(BinaryTree &T,char preorder[],char inorder[],int first,int last)
//给定先序和中序建立二叉树
{
if(first>last)
{
T=NULL;
}
if(first==last)
{
T=(BinaryTree)malloc(sizeof(BTNode));
T->data=preorder[index];
T->leftchild=T->rightchild=NULL;
index++;
}
if(firstdata=preorder[index];
index++;
CreateByPreAndIn(T->leftchild,preorder,inorder,first,loc-1);
CreateByPreAndIn(T->rightchild,preorder,inorder,loc+1,last);
}
}
void CreateByPostAndIn(BinaryTree &T,char postorder[],char inorder[],int first,int last)
//给定后序和中序建立二叉树
{
if(first>last)
{
T=NULL;
}
if(first==last)
{
T=(BinaryTree)malloc(sizeof(BTNode));
T->data=postorder[index];
T->leftchild=T->rightchild=NULL;
index--;
}
if(firstdata=postorder[index];
index--;
CreateByPostAndIn(T->rightchild,postorder,inorder,loc+1,last);
CreateByPostAndIn(T->leftchild,postorder,inorder,first,loc-1);
}
}
void PreOrderTraverse(BinaryTree T)//前序遍历输出二叉树
{
if(T)
{
cout<data<<" ";
PreOrderTraverse(T->leftchild);
PreOrderTraverse(T->rightchild);
}
}
void InOrderTraverse(BinaryTree T)//中序遍历输出二叉树
{
if(T)
{
InOrderTraverse(T->leftchild);
cout<data<<" ";
InOrderTraverse(T->rightchild);
}
}
void PostOrderTraverse(BinaryTree T)//后序遍历输出二叉树
{
if(T)
{
PostOrderTraverse(T->leftchild);
PostOrderTraverse(T->rightchild);
cout<data<<" ";
}
}
void print(BinaryTree T)//打印二叉树
{
cout<<"先序遍历为:\n";
PreOrderTraverse(T);
cout<