【Java】常用二叉树考点

今天复习了一下二叉树考点,包括反转二叉树,二叉树最近公共祖先,找到指定值的路径。
import java.util.*;

public class buildTree {

    private int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    private static List<Node> nodeList = null;

    private static class Node {
        Node leftChild;
        Node rightChild;
        int data;

        Node(int newData) {
            leftChild = null;
            rightChild = null;
            data = newData;
        }
    }

    public static void main(String[] args) {
        buildTree binTree = new buildTree();
        binTree.createBinTree();
        // nodeList中第0个索引处的值即为根节点
        Node root = nodeList.get(0);
        Node node1 = nodeList.get(7);
        Node node2 = nodeList.get(8);

        System.out.println("先序遍历:");
        preOrderTraverse(root);
        System.out.println();

        System.out.println("中序遍历:");
        inOrderTraverse(root);
        System.out.println();

        System.out.println("后序遍历:");
        postOrderTraverse(root);
        System.out.println();

        int height = getHeight(root);
        System.out.println("tree height: " + height);

        int maxWidth = getMaxWidth(root);
        System.out.println("tree max width: " + maxWidth);
        System.out.println();

        int sum = 16;
        findPath(root, sum);

        Node leastCommonAncestor = findLeastCommonAncestor(root, node1, node2);
        System.out.println(leastCommonAncestor.data);

        reverseTree(root);
    }

    private static void reverseTree(Node root) {
        if (root == null) {
            return;
        }
        if ((root.leftChild == null) && (root.rightChild == null)) {
            return;
        }
        Node tmp = root.leftChild;
        root.leftChild = root.rightChild;
        root.rightChild = tmp;
        reverseTree(root.leftChild);
        reverseTree(root.rightChild);
    }
    

    private static Node findLeastCommonAncestor(Node root, Node node1, Node node2) {
        if (root == null) {
            return null;
        }
        if (root == node1 || root == node2) {
            return root;
        }
        Node left = findLeastCommonAncestor(root.leftChild, node1, node2);
        Node right = findLeastCommonAncestor(root.rightChild, node1, node2);
        if (left != null && right != null) {
            return root;
        }
        return left != null ? left : right;
    }




    private static void findPath(Node root, int sum) {
        if (root == null) {
            return;
        }
        Stack<Integer> stack = new Stack<Integer>();
        findPath(root, sum, stack, 0);
    }

    private static void findPath(Node root, int sum, Stack<Integer> stack, int curSum) {
        stack.push(root.data);
        curSum += root.data;

        boolean isLeaf = (root.leftChild == null) && (root.rightChild == null);
        if (isLeaf && curSum == sum) {
            for (Integer e : stack) {
                System.out.println(e);
            }
            System.out.println();
        }

        if (root.leftChild != null) {
            findPath(root.leftChild, sum, stack, curSum);
        }
        if (root.rightChild != null) {
            findPath(root.rightChild, sum, stack, curSum);
        }
        //删除栈顶元素
        stack.pop();
    }



    public void createBinTree() {
        nodeList = new LinkedList<Node>();
        // 将一个数组的值依次转换为Node节点
        for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) {
            nodeList.add(new Node(array[nodeIndex]));
        }
        // 对前lastParentIndex-1个父节点按照父节点与孩子节点的数字关系建立二叉树
        for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) {
            // 左孩子
            nodeList.get(parentIndex).leftChild = nodeList
                    .get(parentIndex * 2 + 1);
            // 右孩子
            nodeList.get(parentIndex).rightChild = nodeList
                    .get(parentIndex * 2 + 2);
        }
        // 最后一个父节点:因为最后一个父节点可能没有右孩子,所以单独拿出来处理
        int lastParentIndex = array.length / 2 - 1;
        // 左孩子
        nodeList.get(lastParentIndex).leftChild = nodeList
                .get(lastParentIndex * 2 + 1);
        // 右孩子,如果数组的长度为奇数才建立右孩子
        if (array.length % 2 == 1) {
            nodeList.get(lastParentIndex).rightChild = nodeList
                    .get(lastParentIndex * 2 + 2);
        }
    }

    /**
     * 先序遍历
     *
     * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
     *
     * @param root
     *            遍历的节点
     */
    public static void preOrderTraverse(Node root) {
        if (root == null)
            return;
        System.out.print(root.data + " ");
        preOrderTraverse(root.leftChild);
        preOrderTraverse(root.rightChild);
    }

    /**
     * 中序遍历
     *
     * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
     *
     * @param root
     *            遍历的节点
     */
    public static void inOrderTraverse(Node root) {
        if (root == null)
            return;
        inOrderTraverse(root.leftChild);
        System.out.print(root.data + " ");
        inOrderTraverse(root.rightChild);
    }

    /**
     * 后序遍历
     *
     * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已
     *
     * @param root
     *            遍历的节点
     */
    public static void postOrderTraverse(Node root) {
        if (root == null)
            return;
        postOrderTraverse(root.leftChild);
        postOrderTraverse(root.rightChild);
        System.out.print(root.data + " ");
    }



    public static int getHeight(Node root) {
        if (root == null) {
            return 0;
        } else {
            int left = getHeight(root.leftChild);
            int right = getHeight(root.rightChild);
            return (left > right ? left : right) + 1;
        }
    }

    public static int getMaxWidth(Node root) {
        Queue<Node> queue = new ArrayDeque<Node>();
        int maxWidth = 1;
        queue.add(root);

        while (true) {
            int len = queue.size();
            if (len == 0) {
                break;
            }
            while (len > 0) {
                Node t = queue.poll();
                len--;
                if (t.leftChild != null) {
                    queue.add(t.leftChild);
                }
                if (t.rightChild != null) {
                    queue.add(t.rightChild);
                }
            }
            maxWidth = Math.max(maxWidth, queue.size());
        }
        return maxWidth;
    }





}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值