数据结构:(代码篇 002) 给定后序和中序遍历,重建这棵树

目录

1.理论依据:

具体情况下:

一般情况下:

2.代码


1.理论依据:


具体情况下:

已知后序遍历:post1、post2、……、postN,中序遍历:in1、in2、……、inN。

由先序遍历的性质可知:preN是当前二叉树根节点的值,然后,在中序遍历中遍历一遍,找到根节点(记为k),k左侧的就是左子树,k右侧的就是右子树。

左子树的长度:numleft=k-1;

那么,先序遍历中左子树的范围:1~1+numleft-1 , 右子树的范围:1+numleft~N-1

          中序遍历中左子树的范围: 1~k-1 ,右子树的范围:k+1~N


一般情况下:

已知后序遍历:postL、……、postR,中序遍历:inL、in2、……、inR。

由先序遍历的性质可知:postR是当前二叉树根节点的值,然后,在中序遍历中过一遍,找到根节点(记为k),k左侧的就是左子树,k右侧的就是右子树。

左子树的长度:numleft=k-inL;

那么,先序遍历中左子树的范围:postL~postL+numleft-1 , 右子树的范围:postL+numleft~postR-1

           中序遍历中左子树的范围: inL~k-1 ,右子树的范围:k+1~inR

2.代码
 

node* create(int postL,int postR,int inL,int inR){
	if(postL>postR){     // 先序序列小于0,则返回 
		return NULL;
	}
	node* root=new node;
	root->data=post[postR];       // 根节点赋值 
	int k;
	for(k=inL;k<inR;k++){        // 在中序遍历中找到根节点 
		if(in[k]==post[postR]){
			break;
		}
	}
	int numLeft=k-inL;     // 左子树的长度 
	//对左子树进行递归 
	root->lchild=create(postL,postL+numLeft-1,inL,k-1); 
	//对右子树进行递归 
	root->rchild=create(postL+numLeft,postR-1,k+1,inR);
    return root; 
}

完整的代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define range 100
#define NULL 0
struct node{
	int data;
	node* lchild;
	node* rchild;
}; 
node* Root=NULL;
int post[range];
int in[range];
node* create(int postL,int postR,int inL,int inR){
	if(postL>postR){     // 先序序列小于0,则返回 
		return NULL;
	}
	node* root=new node;
	root->data=post[postR];       // 根节点赋值 
	int k;
	for(k=inL;k<inR;k++){        // 在中序遍历中找到根节点 
		if(in[k]==post[postR]){
			break;
		}
	}
	int numLeft=k-inL;     // 左子树的长度 
	//对左子树进行递归 
	root->lchild=create(postL,postL+numLeft-1,inL,k-1); 
	//对右子树进行递归 
	root->rchild=create(postL+numLeft,postR-1,k+1,inR);
    return root; 
}
void preorder(node* root){      // 先序遍历 
	if(root==NULL){
		return ;
	}
	printf("%d ",root->data);
	preorder(root->lchild);
	preorder(root->rchild);
} 
void inorder(node* root){       // 中序遍历 
	if(root==NULL){
		return ;
	}
	inorder(root->lchild);
	printf("%d ",root->data);
	inorder(root->rchild);
} 
void postorder(node* root){     // 后序遍历 
	if(root==NULL){
		return ;
	}
	postorder(root->lchild);
	postorder(root->rchild);
	printf("%d ",root->data);
} 
void layerorder(node* root){    // 层次遍历 
	queue<node*> s;
	s.push(root);
	node* temp=NULL;
	while(!s.empty()){
		temp=s.front();
		s.pop();
		printf("%d ",temp->data);
		if(temp->lchild!=NULL) 
		    s.push(temp->lchild);
		if(temp->rchild!=NULL)
		    s.push(temp->rchild);
	}
}
//测试数据: 10 9 8 7 4 5 6 3 2 1 
int main(){
	int i,j;
	cout<<"请输入节点个数:"<<endl;
	cin>>j;
	cout<<"请输入后序遍历:"<<endl;
	for(i=0;i<j;i++)
	cin>>post[i];
	cout<<"请输入中序遍历:"<<endl;
	for(i=0;i<j;i++)
	cin>>in[i];
	Root=create(0,j-1,0,j-1);
	cout<<endl<<endl;
	printf("中序遍历:");
	inorder(Root); 
	cout<<endl;
	printf("先序遍历:");
	postorder(Root); 
	cout<<endl;
	printf("后序遍历:");
	postorder(Root); 
	cout<<endl;
	printf("层序遍历:");
	layerorder(Root); 
	
	return 0;
}
发布了374 篇原创文章 · 获赞 101 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/qq_41325698/article/details/104065982