算法宝典2——Java版本(此系列持续更新,这篇文章目前3道)(有题目的跳转链接)(此份宝典包含了二叉树的算法题)

简介: 算法宝典2——Java版本(此系列持续更新,这篇文章目前3道)(有题目的跳转链接)(此份宝典包含了二叉树的算法题)

一、二叉树的算法题(目前3道)

1. 平衡二叉树(力扣)

题目:给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 ,空树也是平衡二叉树。

思路:

代码:

// 获取二叉树的高度
    public int maxDepth(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftCount = maxDepth(root.left);
        int rightCount = maxDepth(root.right);
        return (leftCount > rightCount) ? leftCount + 1 : rightCount + 1;
    }
    //判断是否为平衡二叉树
    public boolean isBalanced(TreeNode root) {
        //如果为空树,返回null
        if(root == null){
            return true;
        }
        //获取左右子树的高度
        int leftTreeHigh = maxDepth(root.left);
        int righTreeHigh = maxDepth(root.right);
        //isBalanced(root.left) && isBalanced(root.left)是判断左右子树是不是也满足平衡二叉树的定义
        return Math.abs(leftTreeHigh - righTreeHigh) < 2
                && isBalanced(root.left) && isBalanced(root.right);
    }

如果是按照上述代码的思路来写,此算法的时间复杂度就是O(n^2)!!!这是在是太大了!

什么原因造成的呢?

答:我们在求3结点的高度时,其实就把9结点的高度求出来了,但是递归到9结点的时候,又求了一次,导致重复求树的高度,有n个结点,每个结点就要求n次高度,也就是n*n!!!

所以我们可以把代码改一下:

public int maxDepth2(TreeNode root) {
        //空树,证明没有子树,他的高度就是0
        if(root == null){
            return 0;
        }
        int leftH = maxDepth2(root.left);//只要左子树的高度返回是-1,表示左子树不满足平衡二叉树的定义
        if(leftH < 0)
            return -1;
        int rightH = maxDepth2(root.right);//只要右子树的高度返回是-1,表示左子树不满足平衡二叉树的定义
        if (rightH < 0)
            return -1;
        if(Math.abs(leftH - rightH) <= 1){
            return Math.max(leftH,rightH) + 1;//满足定义,返回高度最高的子树,并+1
        }else{
            return -1;//不满足定义,返回-1
        }
    }
    public boolean isBalanced2(TreeNode root) {
        return maxDepth2(root) >= 0;
    }

运行结果:

2.  对称二叉树(力扣)

题目:给你一个二叉树的根节点 root , 检查它是否轴对称。

思路:

和这道判断两个二叉树是不是一样的题目类似:算法宝典1——Java版本(此系列持续更新,这篇文章有20道)(有题目的跳转链接)(此份宝典包含了链表、栈、队列、二叉树的算法题)_木子斤欠木同的博客-CSDN博客

让左子树的左结点和右子树的右子树相比较,然后递归下去,然后就可以判断是不是对称二叉树!!!

代码:

//判断对称树
    public boolean isSymmetricChild(TreeNode leftChild, TreeNode rightChild) {
        //这是路径的判断
        if (leftChild != null && rightChild == null || leftChild == null && rightChild != null) {
            return false;
        }
        if (leftChild == null && rightChild == null) {
            return true;
        }
        //这是值的判断
        if (leftChild.val != rightChild.val) {
            return false;
        }
        return isSymmetricChild(leftChild.left, rightChild.right)
                && isSymmetricChild(leftChild.right, rightChild.left);
    }
    public boolean isSymmetric(TreeNode root) {
        if (root == null) {
            return true;
        }
        return isSymmetricChild(root.left,root.right);
    }

运行结果:

3. 二叉树的层序遍历(力扣)

题目:给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

思路:

代码:

//不带链表的形式
    public void levelOrder1(TreeNode root){
        if(root == null){
            return;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            TreeNode poll = queue.poll();
            System.out.println(poll.val+ " ");
            if(poll.left != null){
                queue.offer(poll.left);
            }
            if(poll.left != null){
                queue.offer(poll.right);
            }
        }
    }
    //带链表的形式
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> List = new ArrayList<>();
        if(root == null){
             return List;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){//第一层循环表示树什么时候遍历完
            int size = queue.size();
            List<Integer> list = new ArrayList<>();
            while(size != 0){//第二层循环表示当前层次的元素数量
                TreeNode cur = queue.poll();
                size--;
                list.add(cur.val);//将元素保存到列表
                if(cur.left != null){
                    queue.offer(cur.left);
                }
                if(cur.right != null){
                    queue.offer(cur.right);
                }
            }
            List.add(list);
        }
        return List;
    }

运行结果:

相关文章
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
91 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
1月前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
1月前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
50 5
|
1月前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
36 0
|
2月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
28 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
2月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
32 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
2月前
|
Java
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
30 1
|
2月前
|
算法 Java C语言
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
26 1
|
1月前
|
算法 Java
JAVA 二叉树面试题
JAVA 二叉树面试题
17 0
|
2月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
30 0