首页 > 试题广场 >

判断一棵满二叉树是否为二叉搜索树

[编程题]判断一棵满二叉树是否为二叉搜索树
  • 热度指数:12553 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

给定一棵满二叉树,判定该树是否为二叉搜索树,是的话打印True,不是的话打印False

说明:
a. 二叉搜索树(Binary Search Tree),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树
b. 满二叉树,除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树
c. 树内节点数不超过 10000,非空节点值为大于0小于65536的整数,空树则输入None,空树我们也认为是二叉搜索树

数据范围:树上节点数满足 ,每个节点的值满足

输入描述:
从根节点开始,逐层输入每个节点的值,空树或空节点输入为None
比如:10,5,15,3,7,13,18


输出描述:
是二叉搜索树的话打印True,不是的话打印False
示例1

输入

10,5,15,3,7,13,18

输出

True
示例2

输入

None

输出

True
示例3

输入

10,5,15,3,4,13,18

输出

False

说明

节点值为 5 的左子节点和右子节点是 3 , 4 都小于根节点 5 ,所以不是二叉搜索树 
import java.util.*;

// 🍎可以先构建整棵树, 再中序遍历, 判断是否递增
// 🍓不过由于满二叉树, i根 2i+1左 2i+2右, 可以不用构建树, 直接中序遍历
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] sp = in.nextLine().split(",");
        if (sp[0].equals("None")) { // 空树
            System.out.print("True");
            return;
        }
        int[] a = new int[sp.length];
        for (int i = 0; i < sp.length; i++) a[i] = Integer.parseInt(sp[i]);

        List<Integer> list = new ArrayList<>();
        dfs(a, 0, list); // 中序遍历

        for (int i = 0; i < list.size() - 1; i++) {  // 判断递增
            if (list.get(i) >= list.get(i + 1)) {
                System.out.print("False");
                return;
            }
        }
        System.out.print("True");
    }

    // 中序
    private static void dfs(int[] a, int i, List<Integer> list) {
        if (i >= a.length) return;
        dfs(a, 2 * i + 1, list);
        list.add(a[i]);
        dfs(a, 2 * i + 2, list);
    }
}

发表于 2025-04-18 10:37:50 回复(0)

先构建二叉树,然后判断是否为二叉搜索树

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String[] res = sc.nextLine().split(",");
            if (res[0].equals("None")) {
                System.out.println("True");
                return;
            }

            TreeNode root = getTree(res);
            boolean flag = isBST(root);

            if (flag) {
                System.out.println("True");
            } else {
                System.out.println("False");
            }
        }
    }

    /**
    * 判断是否是二叉搜索树
    */
    static TreeNode prev = null;
    public static boolean isBST(TreeNode root) {
        if (root == null) return true;

        if (!isBST(root.left)) return false;
        if (prev != null && prev.val >= root.val) {
            return false;
        }
        prev = root;

        return isBST(root.right);
    }


    /**
    * 构建二叉树
    */
    public static TreeNode getTree(String[] res) {
        TreeNode root = new TreeNode(Integer.parseInt(res[0])), p = root;
        int idx = 0;
        Deque<TreeNode> queue = new ArrayDeque<>();
        while (p != null) {
            if (2 * idx + 1 < res.length) {
                p.left = new TreeNode(Integer.parseInt(res[2 * idx + 1]));
                queue.offer(p.left);
            }
            if (2 * idx + 2 < res.length) {
                p.right = new TreeNode(Integer.parseInt(res[2 * idx + 2]));
                queue.offer(p.right);
            }
            p = queue.poll();
            idx++;
        }

        return root;
    }
}

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

    public TreeNode(){}

    public TreeNode(int val) {
        this.val = val;
    }
}
发表于 2022-06-25 11:25:53 回复(0)
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main{
    //递归思路验证
     public static boolean isBalance(List<Integer>A,int pivot){
	     //如果是叶子节点,必满足二叉搜索树定义   
         if((pivot*2+1)>=A.size())
	            return true;
         //若为二叉搜索树,当前节点必满足大于等于左子树的最大值,小于等于右子树的最小值
	        if(LMaxNode(A,pivot*2+1)<=A.get(pivot)&&A.get(pivot)<=RMinNode(A,pivot*2+2))
	        {
	            return isBalance(A,pivot*2+1)&&isBalance(A,pivot*2+2);
	        }else
	            return false;
	    };
    //返回当前树的最小值
	   public static int LMaxNode(List<Integer> A,int pivot){
           while((pivot*2+2)<A.size()){
               pivot=pivot*2+2;
           }
           return A.get(pivot);
       }
    //返回当前树的最大值
     public static int RMinNode(List<Integer> A,int pivot){
             while((pivot*2+1)<A.size()){
                 pivot=pivot*2+1;
             }
             return A.get(pivot);
             
       }
	    public static void main(String[] args){
            //将输入的String转为int数组,剔除None节点
	        Scanner sc=new Scanner(System.in);
	        String[] s=sc.nextLine().split(",");
	        int i=s.length;
	        List<Integer> A=new ArrayList<Integer>();
	        int j=0;
	        while(i>j){
	        	if (!"None".equals(s[j])) {
	        		A.add(Integer.parseInt(s[j]));
				}
	            j++;
	        }
	        System.out.println(isBalance(A,0)==true?"True":"False");
	    }
}

编辑于 2020-06-17 16:04:27 回复(0)
import java.util.Scanner;
public class Main{
    public static boolean isBST(int[] array){
        //不建树 利用满二叉树的性质直接比较大小  
        //左子树(2*i+1) 右子树(2*i+2)
        for(int i = 0; i < array.length/2; i++){
            //左子树小于根节点 右子树大于根节点
            if(array[i] > array[2*i+1] && array[i] < array[2*i+2]){
                //左子树的右子树小于父节点  右子树的左子树大于父节点
                if(i==0||(i%2==1&&array[2*i+2]<array[i/2])||(i%2==0&&array[2*i+1]>array[i/2-1]))
                   continue;
                else
                    return false;
            }
            else
                return false;
        }
        return true;
    }
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String input = in.nextLine();
        String[] s = input.split(",");
        if("None".equals(s[0])){
            System.out.println("True");
            return;
        }
        int[] array = new int[s.length];
        for(int i = 0; i< array.length; i++){
            array[i] = Integer.valueOf(s[i]);
        }
        if(isBST(array))
            System.out.println("True");
        else
            System.out.println("False");
    }
}

发表于 2020-06-03 13:51:23 回复(0)
中序遍历,再检查遍历结果是否是单增序列,不用建树。
import java.util.ArrayList;
import java.util.Scanner;

/**
 * @Author: coderjjp
 * @Date: 2020-05-10 10:19
 * @Description:
 * @version: 1.0
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] s = sc.nextLine().split(",");
        if ("None".equals(s[0])){
            System.out.println("True");
            return;
        }
        int tree[] = new int[s.length];
        for (int i = 0; i < s.length; i++)
            tree[i] = Integer.valueOf(s[i]);
        ArrayList<Integer> midSort = new ArrayList<>();
        midSort(tree, 0, s.length, midSort);
        for (int i = 1; i < midSort.size(); i++)
            if (midSort.get(i) < midSort.get(i-1)){
                System.out.println("False");
                return;
            }
        System.out.println("True");
    }

    private static void midSort(int[] tree, int i, int len, ArrayList<Integer> midSort) {
        if (i >= len)
            return;
        midSort(tree, 2*i+1, len, midSort);
        midSort.add(tree[i]);
        midSort(tree, 2*i+2, len, midSort);
    }
}


发表于 2020-05-10 10:57:02 回复(0)
利用中序遍历严格单调递增。
此外,根据该题目描述,可得节点为数组索引 i 的左儿子节点为(2*i+1),右节点为(2*i+2);
import java.util.ArrayList;
import java.util.Scanner;

public class Main {//二叉搜索树判断

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        String r = "";
        if("None".equals(s))
            r="True";
        else {
            String ss[] = s.split(",");
            int nums[] = new int[ss.length];
            for (int i = 0;i<ss.length;i++){
                nums[i] = Integer.valueOf(ss[i]);
            }
            r=helper(nums);
        }
        System.out.println(r);
        sc.close();
    }

    private static String helper(int[] nums) {
        ArrayList<Integer> r = new ArrayList<>();
        helper2(nums,0,r);
        for(int i=0;i<r.size()-1;i++){
            if(r.get(i)>=r.get(i+1))
                return "False";
        }
        return "True";
    }

    private static void helper2(int[] nums, int i, ArrayList<Integer> r) {
        if(2*i+1<nums.length)
            helper2(nums,2*i+1,r);
        r.add(nums[i]);
        if(2*i+2<nums.length)
            helper2(nums,2*i+2,r);
    }

}


发表于 2020-04-21 19:27:13 回复(0)
import java.util.*;
public class Main {

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    while(sc.hasNext()) {
        String str = sc.nextLine();
        System.out.println(solution(str) ? "True" : "False");
    }    
    sc.close();
}
    private static boolean solution(String str) {
        String[] tree = str.split(",");
        
        if(str.equals("None") || tree.length == 1) return true;
        int base = tree.length + 1;
        int totalDepth = 0;
        while(base/2 != 1){
            totalDepth++;
            base /= 2;
        }
        return isValidBST(tree, 0, 0, totalDepth);
    }
 
    private static boolean isValidBST(String[] tree, int index, int depth, int totalDepth) {
        if (index >= tree.length / 2) return true;
                 
        int val = Integer.parseInt(tree[index]);
        int left = 2 * index + 1, right = 2 * index + 2;
        
        if(!isValidBST(tree, left, depth + 1, totalDepth) || !isValidBST(tree, right, depth + 1, totalDepth)){
            return false;
        }else{
        	totalDepth -= depth;
        	depth = 0;
            int start = 2 * index + 1;
            while(depth < totalDepth){
                for(int i = start; i < start + (int)Math.pow(2,depth); i++){
                    if(val <= Integer.parseInt(tree[i])){
                        return false;
                    }
                }
                for(int i = start + (int)Math.pow(2,depth); i < start + (int)Math.pow(2,depth + 1); i++){              	
                    if(val >= Integer.parseInt(tree[i])){
                        return false;
                    }
                }
                depth++;
                start = 2 * start + 1;
            }
        }
        return true;
    }
}

发表于 2019-11-25 01:30:22 回复(0)
//Java解法 
//这方法的思路是利用层序来先重构二叉树,然后再判断是不是二叉搜索树

运行时间:140ms

占用内存:14052k


import java.util.*;
//定义树结点
class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val){
        this.val=val;
    }
}
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
       //按照顺序存放树结点,由于树结点的左、右结点还没赋值 后面会用到
        Queue<TreeNode> queue=new LinkedList<>();
        String [] str=sc.nextLine().split(",");
                //题意空树或空结点时是输入None
                //判断是否为None,空数也是二叉搜索树
        if(str[0].equals("None")){
            System.out.print("True");
            System.exit(0);
        }
                //定义根结点
        TreeNode head=new TreeNode(Integer.parseInt(str[0]));
        //再保存一个根结点,后面用来判断是否是二叉搜索树用到
                TreeNode root=head;
                //按顺序添加结点
        queue.add(head);
                //判断左结点有没有赋值
        boolean flag=false;
                //重构二叉树代码
        for(int i=1;i<str.length;i++){
                        //添加结点
            TreeNode temp=new TreeNode(Integer.parseInt(str[i]));
            queue.add(temp);
                        //如果没有给左结点赋值,则给左结点赋值
            if(!flag){
                head.left=temp;
                flag=true;
            }
                        //如果左结点赋值,则给右结点赋值
            else{
              head.right=temp;
                               //左、右结点都赋值完了,出队列
                queue.poll();
                          //重新找一个新的结点来赋值左、右结点,按入队顺序来
                head=queue.peek();
                flag=false;
            }
        }
        //找出左子树的最大值
        int max=GetMaxLeft(root.left);
                //找到右子树的最小值
        int min=GetMinRight(root.right);

                    
                //左子树的所有值都要小于根结点的值,所有找出最大值来判断
                //右子树的所有值都要大于根结点的值,所有找出最小值来判断
        //如果不满足这两个条件,直接输出False,后面都不用判断二叉搜索树了
                //不找出最值只能通过90%
                if(root.val<max||root.val>min){
            System.out.print("False");
        }
                //判断是否是二叉搜索树
        else if(check(root)){
            System.out.print("True");
        }
        else{
            System.out.print("False");
        }
    }
    //找左子树的最大值的方法
    public static int GetMaxLeft(TreeNode left){
        int max=left.val;
        LinkedList<TreeNode> list=new LinkedList<>();
        list.add(left);
        while(list.size()>0){
            TreeNode node=list.poll();
            if(node.val>max){max=node.val;}
            if(node.left!=null){
                list.add(node.left);
            }
            if(node.right!=null){
                list.add(node.right);
            }
        }
        return max;
    }
    //找右子树的最小值的方法
     public static int GetMinRight(TreeNode right){
        int min=right.val;
        LinkedList<TreeNode> list=new LinkedList<>();
        list.add(right);
        while(list.size()>0){
            TreeNode node=list.poll();
            if(node.val>min){min=node.val;}
            if(node.left!=null){
                list.add(node.left);
            }
            if(node.right!=null){
                list.add(node.right);
            }
        }
        return min;
    }
    //判断二叉搜索树的方法
        //递归
    public static boolean check(TreeNode root){
     //递归结束条件
          if(root.left==null&&root.right==null) return true;
     else if((root.left.val<root.val)&&(root.right.val>root.val)){
                return check(root.left)&&check(root.right);
            }
        else {
            return false;
        }
    }
}





编辑于 2019-09-12 00:07:26 回复(1)