剑指offerDayN树篇

根据前序中序递归重建二叉树

package offer;

import java.util.Arrays;
import java.util.Stack;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}

/*
前序中序重建二叉树
Arrays.copyOfRange()
主要用于对一个已有的数组进行截取复制,复制出一个左闭右开区间的数组。
 */
public class Test31 {
    //递归调用构建树
    public static TreeNode reConstruct(int[] preOrder, int[] inOrder) {
        //先判空
        if (preOrder.length == 0 || preOrder == null) return null;
        //构建二叉树
        TreeNode root = new TreeNode(preOrder[0]);
        //查找根节点在中序之间的位置下标 每次左子树 跟右子树范围会发生变化
        int index = findIndex(preOrder, inOrder);
        //递归左子树
        //中序index其实就是他的长度
        root.left = reConstruct(Arrays.copyOfRange(preOrder, 1, index + 1), Arrays.copyOfRange(inOrder, 0, index));
        //递归右子树
        root.right = reConstruct(Arrays.copyOfRange(preOrder, index + 1, preOrder.length), Arrays.copyOfRange(inOrder, index + 1, inOrder.length));

        return root;
    }

    /**
     * 根据前序中序查找每次的根节点对应的下标
     *
     * @param preOrder
     * @param inOrder
     * @return
     */
    public static int findIndex(int[] preOrder, int[] inOrder) {
        //每次的根节点都是在变化的
        int root = preOrder[0];
        for (int i = 0; i < preOrder.length; i++) {
            if (inOrder[i] == root)
                return i;
        }
        return -1;
    }

    //二叉树前序遍历 非递归

    /**
     * 用栈实现非递归
     *
     * @param root
     */
    public static void preOrder(TreeNode root) {
        //先判空
        if (root == null)
            return;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            System.out.print(node.val+" ");
            if (node.right != null)
                stack.push(node.right);
            if (node.left != null)
                stack.push(node.left);

        }
    }

    public static void main(String[] args) {
        int[] preOrder = new int[]{1, 2, 4, 7, 3, 5, 6, 8};
        int[] inOrder = new int[]{4, 7, 2, 1, 5, 3, 8, 6};
        TreeNode tree = reConstruct(preOrder, inOrder);
        preOrder(tree);
    }
}

层序遍历+按照节点位置输出层序遍历

树递归专栏:1树的镜像 2树的高度  3是否为平衡二叉树

package offer;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/*
1从上到下层序遍历树
2按照节点个数遍历树
3 二叉树镜像 对二叉树进轴对称
    先对左右子树镜像
    再对子树里面的数值进行求镜像
4求树的深度---递归经典套路
5判断树是不是平衡二叉树
 */
public class Test32 {
    public static void bfsOrder(TreeNode root) {
        //判空
        if (root == null) return;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            System.out.print(node.val + " ");
            if (node.left != null)
                queue.add(node.left);
            if (node.right != null)
                queue.add(node.right);
        }
    }

    /**
     * 按照每行有多少节点返回
     *
     * @param root
     */
    public static List<List<Integer>> bfsOrder2(TreeNode root) {
        //判空
        if (root == null) return null;
        List<List<Integer>> lists = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);

        while (!queue.isEmpty()) {
            int size = queue.size();
            //每次新建一个列表
            List<Integer> temp = new ArrayList<>();
            while (size-- > 0) {
                TreeNode node = queue.poll();
                temp.add(node.val);
                if (node.left != null)
                    queue.add(node.left);
                if (node.right != null)
                    queue.add(node.right);
            }
            lists.add(temp);
        }
        return lists;
    }

    /**
     * 递归
     * 先对左右子树镜像
     * 再对子树里面的数值进行求镜像
     *
     * @param root
     * @return
     */
    public static TreeNode mirrorTree(TreeNode root) {
        if (root == null) return null;
        //递归翻转子节点
        //定义零时变量 右边放到左边 然后再把左边放到右边
        TreeNode temp = root.left;
        root.left = mirrorTree(root.right);
        root.right = mirrorTree(temp);
        return root;

        /*
        写的复杂点
        获得翻转子树
        TreeNode l = mirrorTree(root.left);
        TreeNode r = mirrorTree(root.right);
        子树互换
        root.left = l;
        root.right = r;
        return root;
         */
    }

    /**
     * 递归求二叉树的高度
     * 返回左右子树的高度加1
     *
     * @param root
     * @return
     */
    public static int maxDepth(TreeNode root) {
        if (root == null) return 0;
        int l = maxDepth(root.left);
        int r = maxDepth(root.right);
        return l > r ? l + 1 : r + 1;
    }

    //平衡二叉树 任意节点的左右子树的高度不相差1 就是平衡二叉树

    /**
     * r任意节点
     * 高度相差1
     *
     * @param root
     * @return
     */
    public static boolean isBinarayTree(TreeNode root) {
        if (root == null) return true;
        //先求根节点左右两边子树的的深度差
        int l = maxDepth(root.left);
        int r = maxDepth(root.right);
        //|l-1|<=1
        //并且递归左右子树差都不能大于1
        return l - r >= -1 && l - r <= 1 && isBinarayTree(root.left) && isBinarayTree(root.right);
    }

    public static void main(String[] args) {
//构建一颗树
        TreeNode node6 = new TreeNode(6, null, null);
        TreeNode node5 = new TreeNode(5, null, null);
        TreeNode node4 = new TreeNode(4, null, null);
        TreeNode node3 = new TreeNode(3, node6, null);
        TreeNode node2 = new TreeNode(2, node4, node5);
        TreeNode node1 = new TreeNode(1, node2, node3);
        bfsOrder(node1);
        System.out.println(bfsOrder2(node1));
        System.out.println();
        mirrorTree(node1);
        System.out.println(bfsOrder2(node1));
        System.out.println(maxDepth(node1));
        System.out.println(isBinarayTree(node1));
    }
}

三种层序遍历的方式

package offer;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/*
二叉树的打印
从上到下打印二叉树
1从上到下层序遍历
2分层打印
3之子形打印   特点 用linkedlist  头部插入比arraylist快很多
 */
public class Test33 {
    //基础的层序遍历bfs
    public static void bfsOrders(TreeNode root) {
        //判空
        if (root == null) return;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            System.out.print(node.val + " ");
            if (node.left != null)
                queue.add(node.left);
            if (node.right != null)
                queue.add(node.right);
        }
    }

    //按照每层的节点内容输出
    public static List<List<Integer>> bfsOrders2(TreeNode root) {
        //判空
        if (root == null) return null;
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> list = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            List<Integer> temp = new LinkedList<>();
            while (size-- > 0) {
                TreeNode node = queue.poll();
                temp.add(node.val);
                if (node.left != null)
                    queue.add(node.left);
                if (node.right != null)
                    queue.add(node.right);
            }
            list.add(temp);
        }
        return list;
    }

    //z形输出树的节点
    //奇数在队列后面添加 偶数在队里前面添加

    /**
     * 队列前面添加 queue.add(0,node.val)
     *添加flag指标 判断
     * @param root
     */
    public static List<List<Integer>> bfsOrders3(TreeNode root) {
        //判空
        if (root == null) return null;
        Queue<TreeNode> queue = new LinkedList<>();
        List<List<Integer>> list = new LinkedList<>();
        queue.add(root);
        //每次输出一层
        //设置标识flag flag为true则添加
        boolean flag = true;
        while (!queue.isEmpty()) {
            int size = queue.size();
            List<Integer> temp = new LinkedList<>();
            while (size-->0){
                TreeNode node = queue.poll();
                if (flag) temp.add(node.val);// 从左往右
                else temp.add(0, node.val);//奇数从右往左
                if (node.left != null)
                    queue.add(node.left);
                if (node.right != null)
                    queue.add(node.right);
            }
            flag = !flag;
            list.add(temp);
        }
        return list;
    }

    public static void main(String[] args) {
        TreeNode node6 = new TreeNode(6, null, null);
        TreeNode node5 = new TreeNode(5, null, null);
        TreeNode node4 = new TreeNode(4, null, null);
        TreeNode node3 = new TreeNode(3, node6, null);
        TreeNode node2 = new TreeNode(2, node4, node5);
        TreeNode node1 = new TreeNode(1, node2, node3);
        bfsOrders(node1);
        System.out.println();
        System.out.println(bfsOrders2(node1));
        System.out.println(bfsOrders3(node1));
    }
}


版权声明:本文为carpdiem_fan原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。