《程序员代码面试指南》第三章 二叉树问题 逆时针打印二叉树的边界

题目

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);
    }
}

原文地址:https://www.cnblogs.com/lizhouwei/p/8831010.html