题目
1.第一种情况:打印每层最左和最右的节点以及叶子节点
2.第二种情况:打印最左和最右的节点以及叶子节点
java代码
package com.lizhouwei.chapter3;
/**
* @Description:打印二叉树的边界
* @Author: lizhouwei
* @CreateDate: 2018/4/14 10:39
* @Modify by:
* @ModifyDate:
*/
public class Chapter3_2 {
//------第一种情况:打印每层最左和最右的节点以及叶子节点-------//
public void printEdge1(Node head) {
if (head == null) {
return;
}
//获取树的深度,确定存放边节点值得数组的大小
int dep = getDep(head);
Node[][] edge = new Node[dep][2];
getEdge(head, 0, edge);
//从上到下打印左边界
for (int i = 0; i < edge.length; i++) {
System.out.print(edge[i][0].value + " ");
}
//用递归从左到右打印叶子节点
printLeaf(head, 0, edge);
//打印从下到上打印右边节点
for (int i = edge.length - 1; i >= 0; i--) {
if (edge[i][1] != edge[i][0]) {
System.out.print(edge[i][1].value + " ");
}
}
}
//获取树所有的最左最右节点
public void getEdge(Node head, int level, Node[][] edge) {
if (head == null) {
return;
}
edge[level][0] = edge[level][0] == null ? head : edge[level][0];
edge[level][1] = head;
getEdge(head.left, level + 1, edge);
getEdge(head.right, level + 1, edge);
}
//打印最底部非左右边的叶子节点
public void printLeaf(Node head, int level, Node[][] edge) {
if (head == null) {
return;
}
if (head.left == null && head.right == null && head.value != edge[level][0].value && head.value != edge[level][1].value) {
System.out.print(head.value + " ");
}
printLeaf(head.left, level + 1, edge);
printLeaf(head.right, level + 1, edge);
}
//获取树的深度
public int getDep(Node head) {
if (head == null) {
return 0;
}
int leftDep = getDep(head.left);
int rightDep = getDep(head.right);
return Math.max(leftDep, rightDep) + 1;
}
//------第二种情况:打印最左和最右的节点以及叶子节点-------//
public void printEdge2(Node head) {
if (head == null) {
return;
}
//先打印根节点
System.out.print(head.value + " ");
//如果树不是一个倾斜树
if (head.left != null && head.right != null) {
printLeft(head.left, true);
printRight(head.right, true);
} else {
printEdge2(head.left == null ? head.right : head.left);
}
}
//打印左节点
public void printLeft(Node head, boolean isPrint) {
if (head == null) {
return;
}
//如果是左节点或者是叶子节点,则打印
if (isPrint || head.left == null && head.right == null) {
System.out.print(head.value + " ");
}
//打印左节点
printLeft(head.left, isPrint);
//如果左节点为空,则打印其有节点
printLeft(head.right, isPrint && head.left == null);
}
//打印右节点
public void printRight(Node head, boolean isPrint) {
if (head == null) {
return;
}
//如果是左节点或者是叶子节点,则打印
if (isPrint || head.left == null && head.right == null) {
System.out.print(head.value + " ");
}
//如果右节点为空先打印左节点
printRight(head.left, isPrint && head.right == null);
//如果左节点为空,则打印其有节点
printRight(head.right, isPrint);
}
//测试
public static void main(String[] args) {
Chapter3_2 chapter = new Chapter3_2();
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Node head = NodeUtil.generTree(arr, 0, arr.length - 1);
//第一种标准
System.out.print("第一种标准:");
chapter.printEdge1(head);
System.out.println();
System.out.print("第二种标准:");
chapter.printEdge2(head);
}
}