程序员代码面试指南第二版 33.打印二叉树的边界节点
题目描述
给定一颗二叉树的根节点 root,按照如下两种标准分别实现二叉树的边界节点的逆时针打印。
标准一:
1,根节点为边界节点。
2,叶节点为边界节点。
3,如果节点在其所在的层中是最左的或最右的,那么该节点也是边界节点。
标准二:
1,根节点为边界节点。
2,叶节点为边界节点。
3,树左边界延伸下去的路径为边界节点。
4,树右边界延伸下去的路径为边界节点。
ps:具体请对照样例
输入描述:
第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
输出描述:
输出两行整数分别表示按两种标准的边界节点。
示例1
输入
16 1
1 2 3
2 0 4
4 7 8
7 0 0
8 0 11
11 13 14
13 0 0
14 0 0
3 5 6
5 9 10
10 0 0
9 12 0
12 15 16
15 0 0
16 0 0
6 0 0
输出
1 2 4 7 11 13 14 15 16 12 10 6 3
1 2 4 7 13 14 15 16 10 6 3
第一次做; 如何找到树中每一层的最左节点和最右节点; 前序遍历和后续遍历要掌握牢固!; 超时,通过75%
import java. util. Scanner;
public class Main {
public static void main ( String[ ] args) {
Scanner sc = new Scanner ( System. in) ;
String[ ] str = sc. nextLine ( ) . split ( " " ) ;
int n = Integer. parseInt ( str[ 0 ] ) ;
int rootVal = Integer. parseInt ( str[ 1 ] ) ;
TreeNode[ ] nodes = new TreeNode [ n+ 1 ] ;
for ( int i= 1 ; i<= n; i++ ) {
nodes[ i] = new TreeNode ( i) ;
}
for ( int i= 1 ; i<= n; i++ ) {
str = sc. nextLine ( ) . split ( " " ) ;
int val = Integer. parseInt ( str[ 0 ] ) ;
int left = Integer. parseInt ( str[ 1 ] ) ;
int right = Integer. parseInt ( str[ 2 ] ) ;
nodes[ val] . left = left== 0 ? null: nodes[ left] ;
nodes[ val] . right = right== 0 ? null: nodes[ right] ;
}
TreeNode root = nodes[ rootVal] ;
int height = getHeight ( root) ;
TreeNode[ ] [ ] levelLR = new TreeNode [ height] [ 2 ] ;
getLevelLR ( root, levelLR, 0 ) ;
printEdge1 ( levelLR) ;
System. out. println ( ) ;
printEdge2 ( root) ;
}
public static int getHeight ( TreeNode root) {
if ( root== null)
return 0 ;
return Math. max ( getHeight ( root. left) , getHeight ( root. right) ) + 1 ;
}
public static void getLevelLR ( TreeNode root, TreeNode[ ] [ ] levelMap, int level) {
if ( root== null)
return ;
levelMap[ level] [ 0 ] = levelMap[ level] [ 0 ] == null? root: levelMap[ level] [ 0 ] ;
levelMap[ level] [ 1 ] = root;
getLevelLR ( root. left, levelMap, level+ 1 ) ;
getLevelLR ( root. right, levelMap, level+ 1 ) ;
}
public static void printEdge1 ( TreeNode[ ] [ ] levelLR) {
if ( levelLR== null|| levelLR. length== 0 )
return ;
System. out. print ( levelLR[ 0 ] [ 0 ] . val+ " " ) ;
for ( int i= 1 ; i< levelLR. length; i++ ) {
System. out. print ( levelLR[ i] [ 0 ] . val+ " " ) ;
}
printNormalLeaf ( levelLR[ 0 ] [ 0 ] , levelLR, 0 ) ;
for ( int i= levelLR. length- 1 ; i>= 1 ; i-- ) {
if ( levelLR[ i] [ 0 ] != levelLR[ i] [ 1 ] )
System. out. print ( levelLR[ i] [ 1 ] . val+ " " ) ;
}
}
public static void printNormalLeaf ( TreeNode root, TreeNode[ ] [ ] levelLR, int level) {
if ( root== null)
return ;
if ( root. left== null && root. right== null && root!= levelLR[ level] [ 0 ] && root!= levelLR[ level] [ 1 ] ) {
System. out. print ( root. val+ " " ) ;
}
printNormalLeaf ( root. left, levelLR, level+ 1 ) ;
printNormalLeaf ( root. right, levelLR, level+ 1 ) ;
}
public static void printEdge2 ( TreeNode root) {
if ( root== null)
return ;
System. out. print ( root. val+ " " ) ;
if ( root. left!= null && root. right!= null) {
printLeftEdge ( root. left, true ) ;
printRightEdge ( root. right, true ) ;
}
else {
printEdge2 ( root. left!= null? root. left: root. right) ;
}
}
public static void printLeftEdge ( TreeNode root, boolean print) {
if ( root== null)
return ;
if ( print || ( root. left== null && root. right== null) ) {
System. out. print ( root. val+ " " ) ;
}
printLeftEdge ( root. left, print) ;
printLeftEdge ( root. right, print && root. left== null? true : false ) ;
}
public static void printRightEdge ( TreeNode root, boolean print) {
if ( root== null)
return ;
printRightEdge ( root. left, print && root. right== null? true : false ) ;
printRightEdge ( root. right, print) ;
if ( print || ( root. left== null && root. right== null) ) {
System. out. print ( root. val+ " " ) ;
}
}
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode ( int val) {
this . val = val;
}
}
}