构建、打印二叉树JAVA

判断是否是二叉搜索树

假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

  • 自定义输入输出
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;


//题目描述
//给定一个二叉树,判断其是否是一个有效的二叉搜索树。
//假设一个二叉搜索树具有如下特征:
//节点的左子树只包含小于当前节点的数。
//节点的右子树只包含大于当前节点的数。
//所有左子树和右子树自身必须也是二叉搜索树。
//例如:
//输入:
//    5
//   / \
//  1   3
//     / \
//    4   6
//输出: false


public class demo1 {
    //构造树需要的结点类
    static class TreeNode {
        TreeNode left, right;
        int val;
        public TreeNode(int val) {
            this.val = val;
        }
    }
    public static void main(String[] args) throws IOException {
        //输入描述:
        //第一行两个数n,root,分别表示二叉树有n个节点,第root个节点是二叉树的根
        //接下来共n行,第i行三个数val_i,left_i,right_i,
        //分别表示第i个节点的值val是val_i,左儿子left是第left_i个节点,右儿子right是第right_i个节点。
        //节点0表示空。
        //1<=n<=100000,保证是合法的二叉树
        //输入
        //5 1
        //5 2 3
        //1 0 0
        //3 4 5
        //4 0 0
        //6 0 0
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] s = reader.readLine().split(" ");
        int n = Integer.parseInt(s[0]);
        int root = Integer.parseInt(s[1]);
        TreeNode[] tree = new TreeNode[n + 1];
        int[][] leaf = new int[n + 1][2];
        for (int i = 1; i <= n; i++) {
            String[] ss = reader.readLine().split(" ");
            int val_i = Integer.parseInt(ss[0]);
            int left_i = Integer.parseInt(ss[1]);
            int right_i = Integer.parseInt(ss[2]);
            TreeNode node = new TreeNode(val_i);
            leaf[i][0] = left_i;
            leaf[i][1] = right_i;
            tree[i] = node;
        }
        for (int i = 1; i <= n; i++) {
            int left = leaf[i][0];
            if (left != 0) {
                tree[i].left = tree[left];
            } else {
                tree[i].left =null;
            }
            int right = leaf[i][1];
            if (right != 0) {
                tree[i].right = tree[right];
            } else {
                tree[i].right = null;
            }
        }
        TreeNode head = tree[root];
        boolean flag = isBST(head);
        System.out.print(flag);
    }
    //中序遍历有序
    static boolean isBST(TreeNode node) {
        if (node == null) {
            return true;
        }
        int pre = Integer.MIN_VALUE;
        Stack<TreeNode> s = new Stack<>();
        while (!s.isEmpty() || node != null) {
            while (node != null) {
                s.push(node);
                node = node.left;
            }
            node = s.pop();
            if (node == null) {
                break;
            }
            if (pre > node.val) {
                return false;
            }
            pre = node.val;
            node = node.right;
        }
        return true;
    }
}

ACM模式构建、打印二叉树

使用层序遍历打印

import java.util.*;


public class demo2 {
    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        // 节点的构造函数(默认左右节点都为null)
        public TreeNode(int x) {
            this.val = x;
            this.left = null;
            this.right = null;
        }
    }

    public static void main(String[] args) {
//        Scanner sc = new Scanner(System.in);
//        String[] params = sc.nextLine().split(" ");
//        int[] arr = new int[params.length];
//        for (int i = 0; i < arr.length; i++) {
//            arr[i] = Integer.parseInt(params[i]);
//        }
        int[] arr = new int[]{4,1,6,0,2,5,7,-1,-1,-1,3,-1,-1,-1,8};
        TreeNode root = constructBinaryTree(arr);
        print_binary_tree(root);
    }
    /**
     * 根据数组构建二叉树
     * @param arr 树的数组表示
     * @return 构建成功后树的根节点
     */
    static TreeNode constructBinaryTree(final int[] arr) {
        // 构建和原数组相同的树节点列表
        List<TreeNode> treeNodeList = arr.length > 0 ? new ArrayList<>(arr.length) : null;
        TreeNode root = null;
        // 把输入数值数组,先转化为二叉树节点列表
        for (int i = 0; i < arr.length; i++) {
            TreeNode node = null;
            if (arr[i] != -1) {
                // 用 -1 表示null
                node = new TreeNode(arr[i]);
            }
            treeNodeList.add(node);
            if (i == 0) {
                root = node;
            }
        }
        // 遍历一遍,根据规则左右孩子赋值就可以了
        // 注意这里 结束规则是 i * 2 + 2 < arr.length,避免空指针
        for (int i = 0; i * 2 + 2 < arr.length; i++) {
            TreeNode node = treeNodeList.get(i);
            if (node != null) {
                // 线性存储转连式存储关键逻辑
                node.left = treeNodeList.get(2 * i + 1);
                node.right = treeNodeList.get(2 * i + 2);
            }
        }
        return root;
    }
    //层序打印二叉树
    static void print_binary_tree(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        ArrayList<Integer> temp = new ArrayList<>();
        //根节点入队
        if (root != null) {
            queue.offer(root);
        }
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();//队首元素出队
                //以下代码是不打印null节点
//                temp.add(node.val);
//                if (node.left != null) {
//                    queue.offer(node.left);
//                }
//                if (node.right != null) {
//                    queue.offer(node.right);
//                }
                //以下代码是打印null节点
                if (node != null) {
                    temp.add(node.val);
                    queue.offer(node.left);
                    queue.offer(node.right);
                } else {
                    temp.add(-1);
                }
            }
        }
        for (int x : temp) {
            System.out.print(x + " ");
        }
    }
}

今日推歌

-----《错季》

春的颜色不走进秋季
有些爱情就经不起季节轮替
我情愿被世界隔离
也不愿意去面对着你的善意
夏的炙热不温暖冬季
而我只能停在原地无法破冰
强烈的挣扎以后终于开始脱力
被迫冷静

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星回昭以烂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值