1020. Tree Traversals (25)-PAT甲级真题-Java

参考了柳婼思路,在此感谢柳神。
她的是用C++写成的:传送门
自己是用Java写的。
java中的TreeMap函数可以根据键自动正序排序的,这个跟C++中的Map异曲同工之妙。

import java.util.TreeMap;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	static int[] InOrder;
	static int[] PostOrder;
	static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
	static TreeMap<Integer,Integer> preOrder = new TreeMap<>();//这是先序遍历的顺序,键是从0开始的,按照队列(也就是层次遍历顺序)标记的叶子序号,值则是对应这个叶子输入的对应值。()
	
	public static void main(String[] args) {
		int[] num =readLine();
		PostOrder = readLine();
		InOrder = readLine();
		pre(num[0]-1,0,num[0]-1,0);
		int time = 0;
		for(Integer val: preOrder.values()) {
			System.out.print(val);
			time++;
			if(time < preOrder.values().size()) {
				System.out.print(" ");
			}
		}
	}
	
	public static void pre(int root,int start,int end,int index) {
		//root是后序中  当前树的根 
		//start是中序中 树的起点
		//end是中序中 树的结束点
		/*
		 * 1.递归结束的条件是发现结束点在开始点之后
		 */
		if(end < start) {
			return;
		}
		int i = start;
		while(i < end && InOrder[i] != PostOrder[root])i++;//i为中序中当前树根的下标
		preOrder.put(index, PostOrder[root]);
		/*
		 * 2.开始递归
		 * 左子树递归
		 * 左子树的根求法 是 root(当前树的的后序节点序号)-右子树的个数-1=左子树在后序遍历中最后一个元素(也就是左子树的根)
		 * 而右子树的个数,可以通过 中序中 end-root+1 求出。 
		 * 相当于   root- (end - i ) -1 = root+i - end -1	
		 * 
		 * start(左子树在中序中的起始点)是 start
		 * end(左子树在中序中的结束点)是 i-1       (i为中序中当前树根的下标)
		 * 左子树:(2*root-end-2,start,i-1)
		 * 
		 * 右子树的根:root-1
		 * start(右子树在中序中的起始点)是 i + 1
		 * end(右子树在中序中的结束点)是 end       (i为中序中当前树根的下标)
		 */
		pre(root-end+i-1,start,i-1,index*2+1);//左子树递归。
	//在完全二叉树中,当根的下标从0开始时,它的左孩子下标是2*index+1
		pre(root-1,i+1,end,index*2+2);//右子树递归
	//在完全二叉树中,当根的下标从0开始时,它的左孩子下标是2*index+2
	//这个规律可以自己画图验证
	}
	
	public static int[] readLine() {//封装了输入函数,使用BfferedReader效率高于Scanner
		String str = null;
		try {
			str = bf.readLine();
		}catch(IOException e){
			e.printStackTrace();
		}
		String[] strs = str.split(" ");
		int[] ints = new int[strs.length];
		for(int i = 0;i < ints.length;i++) {
			ints[i] = Integer.parseInt(strs[i]);
		}
		return ints;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值