【机试练习】【C++】【PAT A1020】Tree Traversals

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Xiblade/article/details/82994378

树的遍历常考,此题考根据后续遍历和中序遍历求二叉树,之后输出其层次遍历。
这种题以选择题出题较简单,但机试题求解可能会有一些边界条件。

#include<cstdio>
#include<queue>
using namespace std;

struct Node{
	int data;
	//int level; // 因为题目要求层次遍历,所以添加这个东西 
	Node *lchild;
	Node *rchild;
	Node(){
		data = -1;
		//level = 0;
		lchild = NULL;
		rchild = NULL;
	}
};

const int MAXN = 100;// 以数组存放临时数据

int post[MAXN] = {0};
int in[MAXN] = {0}; 

// 此函数的L 和 R都是左闭右闭的 
Node *create(int postL, int postR, int inL, int inR){
	// 递归边界 :除去中序序列以外的序列为空
	if(postL > postR){
		return 0;
	} 
	// 构造根节点 
	Node *root = new Node;
	root -> data = post[postR];
	// 在中序序列中查找根节点
	int rootNum = -1;
	for(int i = inL; i <= inR; i++){
		if(in[i] == root -> data){
			rootNum = i;
			break;
		}
	}
	// 这种边界应该不会出现 写下来以防万一 
	if(rootNum == -1){
		delete(root);
		return NULL;
	}
	int numL = rootNum - inL; 
	// 那么 现在中序序列中
	// 左子树: [inL, rootNum - 1] 一共 rootNum - inL 
	// 即 numL个 
	// 右子树: [rootNum + 1, inR] 一共 inR - rootNum 个 
	// 后序序列中
	// 以下两行把后续遍历的左右装反了 
	// 左子树: [postR - 1 - numL, postR - 1]
	// 右子树: [postL, postR - 2 - numL] 
	// 左子树: [postL, postL + numL - 1]
	// 右子树: [postL + num , postR - 1] // 注意 这里也要扣1 
	root -> lchild = create(postL, postL + numL - 1, inL, rootNum - 1);
	root -> rchild = create(postL + numL, postR - 1, rootNum + 1, inR);
	return root;
}

void levelOrder(Node *root){
	if(root == NULL){ // 空树  不遍历 
		return;
	}
	queue<Node*> q; // 根节点是存地址 
	q.push(root);
	while(!q.empty()){
		Node *now = q.front();
		printf("%d", now -> data);
		q.pop();
		if(now -> lchild != NULL)
			q.push(now -> lchild);
		if(now -> rchild != NULL)
			q.push(now -> rchild);
		if(!q.empty()) printf(" ");		
	}
	
}

int main(){
	int n = -1;
	scanf("%d", &n);	
	
	if(n == 0){ // 树是空树的情况 
		printf("\n");
		return 0;
	}
	
	// 树不是空树的情况
	// 将后序和中序遍历结果扫描进数组
	for(int i = 0; i < n; i++){
		scanf("%d", &(post[i]));
	} 
	for(int i = 0; i < n; i++){
		scanf("%d", &(in[i]));
	}
	
	// 开始递归地由后续遍历序列到中序遍历序列  
	// 构造二叉树	
	Node *root = create(0, n - 1 , 0, n - 1); // 注意 左闭右闭 
	 
	// 构造完成 开始层次遍历二叉树
	levelOrder(root); 
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Xiblade/article/details/82994378