小猿给定了一棵完全二叉树,树中结点都是正整数,请问该完全二叉树的边界结点从根结点开始以逆时针的顺序排序后形成的序列是什么?
边界结点定义为每层最左边的结点、叶子结点和每层最右边的结点。(同一个结点只能计入一次)
第一行输入一个正整数 N,表示为完全二叉树的结点个数(1 ≤ N ≤ 106)。第二行输入 N 个正整数,表示为该完全二叉树的层序遍历序列。
输出完全二叉树的边界结点从根结点开始以逆时针的顺序排序后形成的序列,以空格分隔。
5 1 2 3 4 5
1 2 4 5 3
二叉树如下:1
/ \
2 3/ \
4 5
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) { this.val = val; }
}
public class Main {
public static ArrayList<Integer> boundary = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] params = br.readLine().split(" ");
int[] elements = new int[n];
for(int i = 0; i < n; i++)
elements[i] = Integer.parseInt(params[i]);
// 重建完全二叉树
TreeNode root = new TreeNode(elements[0]);
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int ptr = 1;
while(ptr < n){
if(!queue.isEmpty()){
TreeNode node = queue.poll();
node.left = new TreeNode(elements[ptr]);
queue.offer(node.left);
ptr ++;
if(ptr < n){
node.right = new TreeNode(elements[ptr]);
queue.offer(node.right);
ptr ++;
}
}
}
// 获得左边界
TreeNode node = root;
boundary.add(node.val);
while(node.left != null){
node = node.left;
boundary.add(node.val);
}
boundary.remove(boundary.size() - 1);
// 后序遍历获得叶子节点
postOrder(root);
boundary.remove(boundary.size() - 1);
// 获得右边界
node = root; // 根节点已经算在左边界内,右边界不考虑
Stack<Integer> rightBoundary = new Stack<>();
while(node.right != null){
node = node.right;
rightBoundary.push(node.val);
}
for(int k = 0; k < boundary.size(); k++)
System.out.print(boundary.get(k) + " ");
// 右边界反着打印
while(!rightBoundary.isEmpty())
System.out.print(rightBoundary.pop() + " ");
}
private static void postOrder(TreeNode node) {
if(node == null) return;
postOrder(node.left);
postOrder(node.right);
// 没有左孩子也没有右孩子,为叶子节点
if(node.left == null && node.right == null) boundary.add(node.val);
}
}