• PAT Advanced 1127 ZigZagging on a Tree (30) [中序后序建树,层序遍历]


    题目

    Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences. And it is a simple standard routine to print the numbers in level-order. However, if you think the problem is too simple, then you are too naive. This time you are supposed to print the numbers in “zigzagging order” — that is, starting from the root, print the numbers level-by-level, alternating between lef to right and right to lef. For example, for the following tree you must output: 1 11 5 8 17 12 20 15.
    Input Specification:
    Each input file contains one test case. For each case, the first line gives a positive integer N (<= 30), the total number of nodes in the binary tree. The second line gives the inorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.
    Output Specification:
    For each test case, print the zigzagging sequence of the tree in a line. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.
    Sample Input:
    8
    12 11 20 17 1 15 8 5
    12 20 17 11 15 8 5 1
    Sample Output:
    1 11 5 8 17 12 20 15

    题目分析

    已知中序序列和后序序列,打印锯齿形序列(奇数层正序,偶数层倒序)

    解题思路

    思路 01

    1. dfs建树(结点左右指针表示树)
    2. bfs遍历树,并设置每个节点分层保存
    3. 锯齿形打印

    思路 02

    1. dfs建树(二维数组表示树,每个数组含两个元素:左孩子节点和右孩子节点)
    2. bfs遍历树,设置每个节点的层级,并分层保存
    3. 锯齿形打印

    Code

    Code 01

    #include <iostream>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn=30;
    int n,pre[maxn],in[maxn],post[maxn];
    struct node {
    	int data;
    	node * left;
    	node * right;
    	int depth;
    };
    vector<node*> result[30];
    node * create(int inL,int inR,int postL,int postR) {
    	if(inL>inR)return NULL;
    	node * root = new node;
    	root->data=post[postR];
    	int k=inL;
    	while(k<inR&&in[k]!=post[postR])k++;
    	root->left=create(inL,k-1,postL,postR-(inR-k)-1);
    	root->right=create(k+1,inR,postR-(inR-k),postR-1);
    	return root;
    }
    void dfs(node * root) {
    	queue<node*> q;
    	root->depth=0;
    	q.push(root);
    	while(!q.empty()) {
    		node * now = q.front();
    		q.pop();
    		result[now->depth].push_back(now);
    		if(now->left!=NULL) {
    			now->left->depth=now->depth+1;
    			q.push(now->left);
    		}
    		if(now->right!=NULL) {
    			now->right->depth=now->depth+1;
    			q.push(now->right);
    		}
    	}
    }
    int main(int argc, char * argv[]) {
    	scanf("%d",&n);
    	for(int i=0; i<n; i++)scanf("%d",&in[i]);
    	for(int i=0; i<n; i++)scanf("%d",&post[i]);
    	node * root = create(0,n-1,0,n-1);
    	dfs(root);
    	printf("%d",result[0][0]->data);
    	for(int i=1;i<30;i++){
    		if(i%2==1){
    			for(int j=0;j<result[i].size();j++){
    				printf(" %d",result[i][j]->data);
    			} 
    		}else{
    			for(int j=result[i].size()-1;j>=0;j--){
    				printf(" %d",result[i][j]->data);
    			} 
    		}
    	}
    	return 0;
    }
    

    Code 02

    #include <iostream>
    #include <vector>
    #include <queue>
    using namespace std;
    struct node {
    	int index;
    	int depth;
    };
    int n,tree[31][2],root;
    vector<int> in,post,result[31];
    void dfs(int &index, int inL, int inR, int postL, int postR) {
    	if(inL>inR)return;
    	index = postR; //当前root
    	//在中序序列中查找当前root
    	int k=inL;
    	while(k<inR&&in[k]!=post[postR])k++;
    	dfs(tree[index][0], inL, k-1, postL, postL+(k-inL)-1);
    	dfs(tree[index][1], k+1, inR, postL+(k-inL), postR-1);
    }
    void bfs() {
    	queue<node> q;
    	q.push(node {root,0});
    	while(!q.empty()) {
    		node temp = q.front();
    		q.pop();
    		result[temp.depth].push_back(post[temp.index]);
    		if(tree[temp.index][0]!=0)q.push(node{tree[temp.index][0],temp.depth+1});
    		if(tree[temp.index][1]!=0)q.push(node{tree[temp.index][1],temp.depth+1});
    	}
    }	
    int main(int argc,char * argv[]) {
    	scanf("%d",&n);
    	in.resize(n+1),post.resize(n+1);
    	for(int i=1; i<=n; i++)scanf("%d",&in[i]);
    	for(int i=1; i<=n; i++)scanf("%d",&post[i]);
    	dfs(root,1,n,1,n);
    	bfs();
    	printf("%d",result[0][0]);
    	for(int i=1;i<31;i++){
    		if(i%2==1){
    			// 奇数行,正序 
    			for(int j=0;j<result[i].size();j++){
    				printf(" %d",result[i][j]);
    			}
    		}else{
    			// 偶数行,逆序 
    			for(int j=result[i].size()-1;j>=0;j--){
    				printf(" %d",result[i][j]);
    			}
    		}
    	} 
    	return 0;
    }
    
  • 相关阅读:
    算法——戳气球(最大乘积和)
    算法——股票买卖问题
    算法——最长上升子序列(DP和二分)
    runtime debug sample
    兼顾站点启动与数据安全性
    SQLServer出发器中使用二进制字段
    OutputCache a2过期时间的设置
    wget 163.com
    SQLServer性能优化
    分页控件设计思路
  • 原文地址:https://www.cnblogs.com/houzm/p/12318528.html
Copyright © 2020-2023  润新知