题目3 : 二叉树垂直遍历
时间限制:1000ms
单点时限:1000ms
内存限制:256MB
描述
对于一个二叉树,输出它的垂直遍历结果;对于同一列的节点,按照从左向右,从上向下的顺序排列。
特殊要求:请使用以下数据结构
class Node
{
int data;
Node left;
Node right
}
例如,对于以下二叉树:
1
/ \
2 3
/
4
垂直遍历的结果是:2 1 4 3
输入
输入包含多组数据。对于每组数据:
第一行是n,表示节点个数(节点编号从0到n-1);当n=-1时,表示输入结束。(1 <= n <= 10)
之后的n行,每一行有三个整数,分别表示:节点的数值,左子树的编号,右子树的编号(编号-1表示节点为空)。
输出
针对每组输入,输出垂直遍历的结果。
样例输入
4
1 1 2
2 -1 -1
3 3 -1
4 -1 -1
-1
样例输出
2 1 4 3
思路:
先对二叉树进行层序遍历,并保存列数,对列数进行排序。
import java.util.*;
class Node {//题目规定用的结构
int data;
Node left;
Node right;
}
class Map {//入队时用的结构,应为要记录他的列,父节点为0,左子树减一,右子树加一。
int i;
Node node;
}
public class test {
static Queue<Map> queue = new LinkedList<>();//队列
static Node test1(int[][] n, int k) {//用输入的数据建立树
Node tree1 = new Node();
tree1.data = n[k][0];
if (n[k][1] == -1) {
tree1.left = null;
} else if (n[k][1] != -1) {
tree1.left = test1(n, n[k][1]);
}
if (n[k][2] == -1) {
tree1.right = null;
} else if (n[k][2] != -1) {
tree1.right = test1(n, n[k][2]);
}
return tree1;
}
public static void main(String[] args) {
List<List<Integer>> lists = new ArrayList<>();
Scanner in = new Scanner(System.in);
int N ;
while (true) {//有多组数据所以要循环
java.util.Map<Integer, List<Integer>> mapput = new TreeMap<>();
N = in.nextInt();
List<Integer> list123 = new ArrayList<>();
if (N == -1) {//当N为-1时,跳出循环,输出结果
break;
}
int[][] n = new int[N][3];
for (int i = 0; i < N; i++) {
for (int j = 0; j < 3; j++) {
n[i][j] = in.nextInt();
}
}
Node tree = test1(n, 0);//父节点
Map map = new Map();
map.i = 0;
map.node = tree;
queue.add(map);//父节点入队列
while (queue.size()!=0) {//队列中所有节点都出来了,结束循环。
map = queue.poll();//出队
int i = map.i;//保存当前这棵树的父节点的列数
tree = map.node;
List<Integer> list = new ArrayList<>();
if (mapput.containsKey(i)) {//查看map里是否已经存在这一列的数据,如果没有直接保存list如果有取出list,在list里添加当前节点的数据,再把list保存回去。
list = mapput.get(i);
list.add(map.node.data);
} else {
list.add(map.node.data);
}
mapput.put(i, list);
if (tree.left != null) {//如果左节点不为空,把父节点的列数减一,入队列
map = new Map();
int j = i;
map.i = j - 1;
map.node = tree.left;
queue.add(map);
}
if (tree.right != null) {//如果右节点不为空,把父节点的列数加一,入队列
map = new Map();
int j = i;
map.i = j + 1;
map.node = tree.right;
queue.add(map);
}
}
List<Integer> list1 = new ArrayList<>();//先把结果保存起来,所有测试用例输入好了,再输出。
for (List<Integer> list : mapput.values()) {
list1.addAll(list);
}
lists.add(list1);
}
for (List<Integer> li:lists) {//输出结果
for (int j : li) {
System.out.print(j+" ");
}
System.out.println();
}
}
}