二叉搜索树的判断+平衡二叉树的判断

一、认识二叉树

  二叉树                       二叉树                          二叉树                                      二叉搜索树                                                                     

  满二叉树                                           平衡二叉树                                           二叉搜索树

二、二叉搜索树

1、判断二叉树是否是二叉搜索树

核心代码:

/**
     * 判断二叉树是否是二分搜索树
     * @param curr
     * @return
     */
    public boolean isBst(TreeNode curr){
        List<Integer>list = new ArrayList<>();
        inOrder(curr,list);
        for(int i=1;i<list.size();i++){
            if(list.get(i) < list.get(i-1)){
                return false;
            }
        }
        return true;
    }
/**
     * 中序遍历二叉树,将二叉树中的节点值添加到list集合中
     * @param curr
     * @param list
     */
    public void inOrder(TreeNode curr, List<Integer> list){
        if(curr == null){
            return;
        }
        inOrder(curr.left, list);
        list.add(curr.val);
        inOrder(curr.right, list);
    }

2、判断二叉树是否是平衡二叉树(通过判断平衡因子是否超过1)

核心代码:

/**
     * 获取二叉树的平衡因子
     * @param curr
     * @return
     */
    public int balanceFactor(TreeNode curr){
        if(curr == null){
            return 0;
        }
        return Math.abs(getheight(curr.right) - getheight(curr.left));
    }
/**
     * 获取二叉树的高度
     * @return
     */
    public int getheight(TreeNode curr){
        if(curr == null){
            return 0;
        }
        return curr.height;
    }

3、中序图形效果打印二叉树

public class TreePrint<E> {
    private final List<TreeNode> mid = new ArrayList<>();//记录bst树的节点
    private final Map<TreeNode, Integer> map = new HashMap<>();//记录节点及位置

    private Queue<E> queue = new ArrayDeque<>();
    private TreeNode root;

    public TreePrint() {
    }

    public TreePrint(TreeNode root) {
        this.root = root;
    }

    /**
     * 中序遍历
     *
     * @param root 树的根节点
     */
    public void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        mid.add(root);
        inOrder(root.right);
    }

    /**
     * 使用Map记录节点及位置
     *
     * @param root
     */
    public void init(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root);
        for (int i = 0; i < mid.size(); i++) {
            map.put(mid.get(i), i);
        }
    }

    /**
     * 打印同一层的节点,使用|线和值进行拼接打印
     *
     * @param TreeNodes
     */
    void printLevelTreeNodes(List<TreeNode> TreeNodes) {
        StringBuilder VLine = new StringBuilder();
        StringBuilder dataLine = new StringBuilder();
        StringBuilder line = new StringBuilder();
        int lastTreeNodeIndex = 0;
        int lastRightIndex = 0;

        for (TreeNode TreeNode : TreeNodes) {
            int x = map.get(TreeNode);
            String addEmpty = getEmpty(x - lastTreeNodeIndex);
            lastTreeNodeIndex = x;
            VLine.append(addEmpty).append("|");//竖线拼接
            dataLine.append(addEmpty).append(TreeNode.val); //值拼接

            TreeNode left = TreeNode.left;
            TreeNode right = TreeNode.right;
            String leftLine = null;
            String rightLine = null;

            int leftIndex = -1;
            int rightIndex = -1;
            if (left != null) {
                leftIndex = map.get(left);
                leftLine = getLineToChildren(x - leftIndex);
            }
            if (right != null) {
                rightIndex = map.get(right);
                rightLine = getLineToChildren(rightIndex - x);
            }

            String curLine = (leftLine == null ? "" : leftLine) + "|" + (rightLine == null ? "" : rightLine);
            if (leftLine == null && rightLine == null) curLine = "";
            //线段之间的间隔
            int dif = (leftIndex == -1 ? x : leftIndex) - lastRightIndex;
            String difEmpty = getEmpty(dif);
            line.append(difEmpty).append(curLine);//拼接线段
            lastRightIndex = rightIndex == -1 ? x : rightIndex;
        }
        System.out.println(VLine + "\n" + dataLine + "\n" + line);
    }

    String getEmpty(int x) {
        StringBuilder empty = new StringBuilder();
        for (int i = 0; i < x; i++) {
            empty.append("\t");
        }
        return empty.toString();
    }


    //链接子线段的长度
    String getLineToChildren(int end) {
        StringBuilder line = new StringBuilder();
        if (end == 0) return line.toString();
        for (int i = 0; i < end; i++) {
            line.append("____");
        }
        return line.toString();
    }

    /**
     * 扫描每一行中每一个节点的左右节点
     *
     * @param lineTreeNodes 每一行的节点
     */
    public void topToDownLevelPrint(List<TreeNode> lineTreeNodes) {
        if (lineTreeNodes.isEmpty()) return;

        printLevelTreeNodes(lineTreeNodes);//打印同一层的节点

        List<TreeNode> children = new ArrayList<>();  //记录当前节点下的所有子节点
        //记录当前节点下的所有左右节点
        for (TreeNode currentTreeNode : lineTreeNodes) {
            if (currentTreeNode.left != null) children.add(currentTreeNode.left);
            if (currentTreeNode.right != null) children.add(currentTreeNode.right);
        }
        topToDownLevelPrint(children);//递归打印下一层节点
    }

    public void print(TreeNode root) {
        init(root);
        topToDownLevelPrint(new ArrayList<TreeNode>() {{
            add(root);
        }});
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值