Java关于树的遍历,判断对称,平衡,子树等常见题型集合

  •  树的前序遍历,中序遍历,后续遍历,层序遍历,递归和非递归

  • 树的重建,给定前序和中序的数组,重建整棵树

  • 判断树是否对称(isSymmetrical),是否平衡(isBanlanced),是否为子树(isSubTree)

  • 给定一个target,求路径上节点值之和为target的路径

  • 树的深度

 

package DataStrcuture;

import java.util.*;

/**
 * @Author: JackYe
 * @CreateDate: 2019/6/3 15:37
 * @Description: java类作用描述
 * @UpdateUser: 更新者
 * @UpdateDate: 2019/6/3 15:37
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */

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

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

public class BinaryTree {

    public TreeNode root;

    public void insert(int val) {
        TreeNode node = new TreeNode(val);
        if (root == null) {
            root = node;
        } else {
            TreeNode newHead = root;
            TreeNode parent;
            while (true) {
                parent = newHead;
                if (node.val < newHead.val) {
                    newHead = newHead.left;
                    if (newHead == null) {
                        parent.left = node;
                        return;
                    }
                } else {
                    newHead = newHead.right;
                    if (newHead == null) {
                        parent.right = node;
                        return;
                    }

                }
            }
        }
    }

    public void buildTree(int[] data) {
        for (int i = 0; i < data.length; i++) {
            insert(data[i]);
        }

    }

    //前序遍历  中左右   (深度遍历)
    public void PreOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val + " ");
        PreOrder(root.left);
        PreOrder(root.right);
    }


    //前序遍历(非递归)  中左右   (深度遍历)
    public void PreOrder2(TreeNode root, int N) {

        if (root == null) {
            return;
        }

        TreeNode[] tree = new TreeNode[N];
        TreeNode newHead = root;
        int index = 0;

        while (newHead != null || index > 0) {

            while (newHead != null) {
                System.out.print(newHead.val + " ");
                tree[index++] = newHead;
                newHead = newHead.left;
            }
            newHead = tree[--index];
            newHead = newHead.right;
        }


    }


    //中序遍历  左中右
    public void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    }

    /*中序遍历 非递归算法*/
    public void inOrder2(TreeNode root, int N) {
        if (root == null) {
            return;
        }

        TreeNode[] tree = new TreeNode[N];
        TreeNode newHead = root;
        int index = 0;

        while (newHead != null || index > 0) {
            while (newHead != null) {
                tree[index++] = newHead;
                newHead = newHead.left;
            }
            newHead = tree[--index];
            System.out.print(newHead.val + " ");
            newHead = newHead.right;
        }

    }


    //后续遍历 左右中
    public void postOrder(TreeNode root) {
        if (root == null) {
            return;
        }

        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val + " ");
    }

    /*难度较大  后续遍历 非递归*/
    public void postOrder2(TreeNode root, int N) {
        if (root == null) {
            return;
        }
        TreeNode[] tree = new TreeNode[N];
        TreeNode newHead = root;
        int index = 0;
        TreeNode lastNode = null;
        while (newHead != null || index > 0) {
            while (newHead != null) {
                tree[index++] = newHead;
                newHead = newHead.left;
            }
            newHead = tree[index - 1];
            if (newHead.right == null || newHead.right == lastNode) {
                System.out.print(newHead.val + " ");
                lastNode = newHead;
                index--;
                newHead = null;

            } else {
                newHead = newHead.right;
            }

        }

    }

    /*后续遍历 非递归*/
    public void postOrder2(TreeNode root) {
        Stack stack1 = new Stack();
        Stack stack2 = new Stack();
        stack1.push(root);
        while (!stack1.isEmpty()) {
            root = stack1.pop();
            stack2.push(root);
            if (root.left != null) {
                stack1.push(root.left);
            }
            if (root.right != null) {
                stack1.push(root.right);
            }

        }
        while (!stack2.isEmpty()) {
            System.out.print(stack2.pop().val + " ");
        }

    }


    //层序遍历 从左至右 (广度遍历)
    public ArrayList> levelOrder(TreeNode root) {
        ArrayList> result = new ArrayList<>();
        if (root == null) {
            return result;
        }


        Queue queue01 = new LinkedList<>();
        Queue queue02 = new LinkedList<>();
        TreeNode node;
        ArrayList data;
        queue01.offer(root);
        while (!queue01.isEmpty() || !queue02.isEmpty()) {

            if (!queue01.isEmpty()) {
                data = new ArrayList<>();
                while (!queue01.isEmpty()) {
                    node = queue01.poll();
                    data.add(node.val);
                    if (node.left != null) {
                        queue02.offer(node.left);
                    }
                    if (node.right != null) {
                        queue02.offer(node.right);
                    }
                }
                result.add(data);
            }

            if (!queue02.isEmpty()) {
                data = new ArrayList<>();
                while (!queue02.isEmpty()) {
                    node = queue02.poll();
                    data.add(node.val);
                    if (node.left != null) {
                        queue01.offer(node.left);
                    }
                    if (node.right != null) {
                        queue01.offer(node.right);
                    }
                }
                result.add(data);
            }
        }
        return result;

    }

    //如果已知先序遍历和中序遍历,如何求后续遍历
    public TreeNode reconstructTree(int[] preOrder, int[] inOrder) {
        int pi = 0;
        int pj = preOrder.length - 1;
        int ni = 0;
        int nj = inOrder.length;
        HashMap hashMap = new HashMap<>();
        for (int i = 0; i < inOrder.length; i++) {
            hashMap.put(inOrder[i], i);
        }

        return reconstructCore(preOrder, pi, pj, inOrder, ni, nj, hashMap);
    }

    public TreeNode reconstructCore(int[] preOrder, int pi, int pj, int[] inOrder, int ni, int nj, HashMap map) {

        if (pi > pj) {
            return null;
        }
        TreeNode root = new TreeNode(preOrder[pi]);
        int index = (int) map.get(preOrder[pi]);
        root.left = reconstructCore(preOrder, pi + 1, pi + index - ni, inOrder, ni, index - 1, map);
        root.right = reconstructCore(preOrder, pi + index - ni + 1, pj, inOrder, index + 1, nj, map);
        return root;
    }

    //判断是否是二叉树的子结构
    public boolean isSubTree(TreeNode root, TreeNode subRoot) {
        boolean flag = false;
        if (subRoot == null || root == null) {
            return false;
        }
        if (root.val == subRoot.val) {
            flag = isSubTreeCore(root, subRoot);
        } else {
            flag = isSubTree(root.left, subRoot);
            if (flag == false) {
                flag = isSubTree(root.right, subRoot);
            }
        }
        return flag;
    }

    public boolean isSubTreeCore(TreeNode root, TreeNode subRoot) {
        if (root == null && subRoot != null) {
            return false;
        }
        if (root == null && subRoot == null) {
            return true;
        }
        if (root != null && subRoot == null) {
            return true;
        }
        if (root.val == subRoot.val) {
            return isSubTreeCore(root.left, subRoot.left) && isSubTreeCore(root.right, subRoot.right);
        } else {
            return false;
        }
    }

    //给出根节点和一个整数,返回路径,路径上节点的和为target
    int count = 0;
    ArrayList arrayList = new ArrayList<>();

    ArrayList> finalList = new ArrayList<>();

    public ArrayList> FindPath(TreeNode root, int target) {

        if (root == null || target <= 0) {
            return finalList;
        }
        FindPathCore(root, target);
        Collections.sort(finalList, new Comparator>() {
            @Override
            public int compare(ArrayList o1, ArrayList o2) {
                return o1.size() - o2.size();
            }
        });
        return finalList;

    }

    private void FindPathCore(TreeNode root, int target) {

        if (root == null) {
            return;
        }
        count += root.val;
        arrayList.add(root.val);
        FindPathCore(root.left, target);
        FindPathCore(root.right, target);
        if (count == target) {
            finalList.add(new ArrayList<>(arrayList));
        }
        count = count - root.val;
        arrayList.remove(arrayList.size() - 1);
    }

    //给出一颗树求取树的深度(即深度的值为根节点到叶子节点最长的路径)
    public int getDepth(TreeNode root) {
        Queue queue = new LinkedList<>();
        if (root != null) {
            queue.offer(root);
        }
        int lastCount = 1;
        int count = 0;
        int deepth = 0;
        while (!queue.isEmpty()) {
            TreeNode newHead = queue.poll();
            count++;
            if (newHead.left != null) {
                queue.offer(newHead.left);
            }
            if (newHead.right != null) {
                queue.offer(newHead.right);
            }
            if (count == lastCount) {
                deepth++;
                count = 0;
                lastCount = queue.size();
            }
        }
        return deepth;
    }

    //判断树的结构是否为对称的二叉树
    public boolean isSymmetrical(TreeNode root) {
        if (root == null) {
            return false;
        }
        return isSymmetrical(root.left, root.right);
    }

    private boolean isSymmetrical(TreeNode right, TreeNode left) {
        if (right == null && left == null) {
            return true;
        }
        if (right != null && left != null && right.val == left.val) {
            return isSymmetrical(left.left, right.right) && isSymmetrical(left.right.right.right);
        }
        return false;
    }

    //判断该树是否为平衡二叉树

    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return false;
        }
        int gap = 0;
        int leftDepth = height(root.left);
        int rightDepth = height(root.right);
        if (Math.abs(leftDepth - rightDepth) > 1) {
            return false;
        } else {
            return isBalanced(root.left) && isBalanced(root.right);
        }
    }

    private int height(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftDepth = height(root.left);
        int rightDepth = height(root.right);
        if (Math.abs(leftDepth - rightDepth) > 1) {
            return -1;
        }
        return Math.max(leftDepth, rightDepth) + 1;
    }

    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        int[] data = {2, 8, 7, 4, 9, 3, 1, 6, 7, 5};
        int pre[] = new int[]{1, 2, 4, 7, 3, 5, 6, 8};
        int in[] = new int[]{4, 7, 2, 1, 5, 3, 8, 6};

        binaryTree.buildTree(data);
        System.out.println("二叉树的前序遍历");
        binaryTree.PreOrder(binaryTree.root);
        System.out.println("\n二叉树的前序遍历(非递归)");
        binaryTree.PreOrder2(binaryTree.root, data.length);
        System.out.println("\n二叉树的中序遍历");
        binaryTree.inOrder(binaryTree.root);
        System.out.println("\n二叉树的中序遍历(非递归)");
        binaryTree.inOrder2(binaryTree.root, data.length);
        System.out.println("\n二叉树的后序遍历");
        binaryTree.postOrder(binaryTree.root);
        System.out.println("\n二叉树的后序遍历(非递归1)");
        binaryTree.postOrder2(binaryTree.root);
        System.out.println("\n二叉树的后序遍历(非递归2)");
        binaryTree.postOrder2(binaryTree.root, data.length);
        System.out.println("\n二叉树的层序遍历");
        binaryTree.levelOrder(binaryTree.root);
        System.out.println("\n二叉树重建");
        TreeNode root = binaryTree.reconstructTree(pre, in);
        System.out.println("是否是树的子结构");
        TreeNode a = new TreeNode(10);
        TreeNode b = new TreeNode(5);
        TreeNode c = new TreeNode(12);
        TreeNode d = new TreeNode(4);
        TreeNode e = new TreeNode(7);
        a.left = b;
        a.right = c;
        b.left = d;
        b.right = e;
        System.out.println(binaryTree.isSubTree(b, a));

        System.out.println("二叉树中的路径满足22");

        System.out.println(binaryTree.FindPath(a, 22));

        System.out.println("二叉树的深度" + binaryTree.getDepth(a));

        System.out.println("二叉树是否对称" + binaryTree.isSymmetrical(a));
    }


}

 

你可能感兴趣的:(Java学习)