【二叉树练习2】

news2025/1/15 6:53:41

文章目录

  • 判断是否是完全二叉树
  • 找出p和q的最近的公共祖先
  • 非递归实现前序遍历
  • 非递归实现中序遍历
  • 非递归实现后序遍历


判断是否是完全二叉树

    boolean isCompleteTree(TreeNode root){
        if (root == null){
            return true;
        }
        //创建队列
        Queue<TreeNode> queue = new LinkedList<>();
        //把根放进队列里
        queue.offer(root);
        while (!queue.isEmpty()){
        //把出队列的放进cur里
            TreeNode cur = queue.poll();
            //当cur不等于空时,把cur的左子树和右子树放进队列
            if (cur != null){
                queue.offer(cur.left);
                queue.offer(cur.right);
            }else{
            //如果cur放进了null,说明要跳出队列进入判断环节
                break;
            }
        }
        while(!queue.isEmpty()){
            TreeNode tmp = queue.peek();//瞄一眼队列的数
            if (tmp == null){
                queue.poll();
            }else{
            //遇到不为空的说明不是完全二叉树
                return false;
            }
        }
        //来到这里说明tmp全部是空的,是完全二叉树
        return true;

    }

找出p和q的最近的公共祖先

1.root节点是p或q其中的一个,那么root就是最近的公共祖先
在这里插入图片描述
2.p和q分别在root的两侧,那么root是最近的公共祖先
在这里插入图片描述
3.p和q在root的同一侧
在这里插入图片描述
原理:root还是在遍历这棵树,遇到p或q就返回。


    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

        if (root == null) return null;
        if (root == p || root == q) {
            return root;
        }
        TreeNode leftTree = lowestCommonAncestor(root.left, p, q);
        TreeNode rightTree = lowestCommonAncestor(root.left, p, q);
        if (leftTree != null && rightTree != null) {
            return root;
        } else if (leftTree != null) {
            return leftTree;

        } else {
            return rightTree;
        }
    }

还有第二种方法
大概意思就是:找p那条路径,和q那条路径出现的节点,然后放进两个栈里,保证两个栈的数相同,多的去掉,然后栈中相同的元素就是他们最近的公共祖先。
在这里插入图片描述

public class BinaryTree {
    static class TreeNode{
        public char val;
        public  TreeNode left;
        public  TreeNode right;

        public TreeNode(char val) {
            this.val = val;
        }
    }
    public TreeNode creatTree(){
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.left = F;
        C.right = G;
        E.right = H;

        return A;
    }

    public TreeNode lowestCommonAncestor2(TreeNode root,TreeNode p,TreeNode q){
        if(root == null) return null;
        //创建两个栈
        Stack<TreeNode> stackP = new Stack<>();
        Stack<TreeNode> stackQ = new Stack<>();
        //两条路径
        getPath(root,p,stackP);
        getPath(root,q,stackQ);
        //大小
        int sizeP = stackP.size();
        int sizeQ = stackP.size();
        if (sizeP > sizeQ){
            int size = sizeP - sizeQ;
            while (size != 0){
                stackP.pop();
                size--;
            }
        }else {
            int size = sizeQ - sizeP;
            while (size != 0){
                stackQ.pop();
                size--;
            }
        }
        //两个栈元素一样多
        while(!stackP.isEmpty() && !stackQ.isEmpty()){
            if (stackP.peek() == stackQ.peek()){
                return stackP.peek() ;
            }else{
                stackP.pop();
                stackQ.pop();
            }
        }
        return null;

    }

    private boolean getPath(TreeNode root, TreeNode node, Stack<TreeNode> stack){
        if (root == null || node == null){
            return false;
        }
        stack.push(root);
        if (root == node){
            return true;
        }
        boolean flg1 = getPath(root.left, node, stack);
        if(flg1){
            return true;
        }
        boolean flg2 = getPath(root.right, node, stack);
        if(flg2){
            return true;
        }
        stack.pop();
        return false;

    }
}

非递归实现前序遍历

    //递归实现前序遍历
    void preOrder(TreeNode root){
        //根左右
        if(root == null){
            return;
        }
        System.out.print(root.val+" ");
        preOrder(root.left);
        preOrder(root.right);

    }
//非递归实现前序遍历
    void preOrderNor(TreeNode root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;

        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                System.out.print(cur.val + " ");
                cur = cur.left;
            }

            TreeNode top = stack.pop();
            cur = top.right;
            //1.为空,返回;不为空创建栈,让cur=root;
            //当cur!=null时,把cur放进栈里,并打印cur.val;再让cur=root.left。
            //当cur==null时,让top=栈顶元素,然后让cur=top.right
        }
    }

非递归实现中序遍历

    //中序遍历
    void inOrder(TreeNode root){
        //左根右
        if(root == null){
            return;
        }
        inOrder(root.left);
        System.out.print(root.val+" ");
        inOrder(root.right);

    }
    //非递归中序遍历
    void inorderNor(TreeNode root){
        if (root == null){
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while(cur != null || !stack.isEmpty()){
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            System.out.print(top.val+" ");
            cur = top.right;
        }
        //不为空,创建栈,让cur=root,把cur放进栈里,然后遍历cur的左边。
        //直到cur遇到空,说明cur的左边遍历完了
        //让top=栈顶元素,并打印top的值,让cur=top.right。

    }

非递归实现后序遍历

    //后序遍历
    void postOrder(TreeNode root){
        //左右根
        if(root == null){
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val+" ");
    }
    //非递归后序遍历
    void postOrderNor(TreeNode root){
        if (root == null){
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        TreeNode prev = null;
        while(cur != null || !stack.isEmpty()){
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
        }
        TreeNode top = stack.peek();
        if (top.right == null || top.right == prev){
            System.out.print(top.val+" ");
            stack.pop();
            prev = top;
        }else{
            cur = top.right;
        }
        //先创建栈,让cur=root,cur不等于空或者栈不为空,当cur不等于空时,让cur入栈,然后让cur=cur.left,
        //直到当cur等于空时,定义prev=null;让top=瞄一眼栈顶元素,如果等于空或者top.right=prev进入循环,
        // 循环内打印top.val,并且出栈,然后让prev=top,否则让cur=cur.right
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1401201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (183)-- 算法导论13.4 7题

七、用go语言&#xff0c;假设用 RB-INSERT 将一个结点 x 插入一棵红黑树&#xff0c;紧接着又用 RB-DELETE 将它从树中删除。结果的红黑树与初始的红黑树是否一样&#xff1f;证明你的答案。 文心一言&#xff1a; 首先&#xff0c;我们需要明确RB-INSERT和RB-DELETE的基本操…

“gradle project sync failed”

很久没打开AndroidStudio了&#xff0c;打开电脑发现这个软件都没了。重新安装后创建项目不成功&#xff0c;就提示了这个错误。 错误原因 “gradle project sync failed”&#xff1a;gradle没有配置成功。在安卓项目下找到目标文件&#xff1a;gradle --> wrapper -->…

机械设计-哈工大课程学习-螺旋传动

二、摩擦类型 1、静态摩擦&#xff1a;这是身体静止时所经历的摩擦。换句话说&#xff0c;就是身体有运动倾向时的摩擦力。 2、动态摩擦&#xff1a;这是身体在运动时所经历的摩擦。也称为动摩擦。动摩擦有以下两种类型&#xff1a; ①滑动摩擦&#xff1a;一个物体在另一个…

赛车游戏简单单车C语言版

#include<stdio.h> #include<easyx.h> #include<time.h>#define WIDTH 512 #define HEIGHT 768//定义一个汽车类 struct FCar {//坐标float x, y;// 汽车种类int type;//汽车速度float speed; };//定义全局变量 图片坐标 IMAGE BG_IMG; //背景图片坐标 float…

SV学习——数据类型(1)

文章目录 1. 内建数据类型2. 用户自定义3. 枚举类型 1. 内建数据类型 SV中引入新的数据类型logic&#xff0c;SV作为侧重于验证的语言&#xff0c;并不十分关切logic对应的逻辑应该被综合位寄存器还是线网&#xff0c;因为logic被使用的场景如果是验证环境&#xff0c;那么它只…

AI对比:ChatGPT与文心一言的异同与未来

文章目录 &#x1f4d1;前言一、ChatGPT和文心一言概述1.1 ChatGPT1.2 文心一言 二、ChatGPT和文心一言比较2.1 训练数据与知识储备2.2 语义理解与生成能力2.2 应用场景与商业化探索 三、未来展望3.1 模型规模与参数数量不断增加3.2 多模态交互成为主流3.3 知识图谱与大模型的结…

如何在 Ubuntu / Raspbian 上安装 MariaDB

Raspberry Pi OS&#xff08;原为Raspbian&#xff09;是为树莓派基于Debian开发的操作系统。 从2015年起&#xff0c;树莓派基金会正式将其作为树莓派的官方操作系统。 Raspbian是由Mike Thompson和Peter Green创建的一个独立项目。第一个版本于2012年6月发布&#xff0c;至…

Unity中实现捏脸系统

前言 目前市面上常见的捏脸一般是基于BlendShapes和控制骨骼点坐标两种方案实现的。后者能够控制的精细程度更高&#xff0c;同时使用BlendShapes来控制表情。 控制骨骼点坐标 比如找到控制鼻子的骨骼节点修改localScale缩放&#xff0c;调节鼻子大小。 BlendShapes控制表…

modelscope下载模型

# 私有模型下载&#xff0c;前提是您有响应模型权限 方法1 git lfs install git clone http://oauth2:your_git_tokenwww.modelscope.cn/<namespace>/<model-name>.git 如何获取git token 用您的账号登录https://www.modelscope.cn &#xff0c;在个人中心->访…

10本审稿及出版效率均较好的医学SCI期刊参数分享!

常笑医学整理了适合医务工作者进行论文投稿的医学SCI期刊&#xff0c; 审稿及出版效率均较好&#xff0c;附期刊详细参数&#xff0c;供大家参考。 1.CLINICAL CHEMISTRY AND LABORATORY MEDICINE&#xff08;临床化学与实验医学&#xff09; &#xff08;详细投稿信息请点击刊…

【Java】Maven的安装与配置

初识Maven Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构 提供了一套标准化的构建流程&#xff08;编译&#xff0c;测试&#xff0c;打包&#xff0c;发布……&#xff09; 提供了一套依赖管理机制 标准化的…

解决springboot+mybatisplus返回时间格式带T

原因&#xff1a;我service实现类的代码是 Overridepublic Map<String, Object> queryDictPage(Map<String, Object> queryMap) {Map<String,Object> map new HashMap<>();QueryWrapper<Dict> wrapper new QueryWrapper<>(); // …

5G基站节能及数字化管理解决方案

截至2023年10月&#xff0c;我国5G基站总数达321.5万个&#xff0c;占全国通信基站总数的28.1%。然而&#xff0c;随着5G基站数量的快速增长&#xff0c;基站的能耗问题也逐渐日益凸显&#xff0c;基站的用电给运营商带来了巨大的电费开支压力&#xff0c;降低5G基站的能耗成为…

系统问题排查定位流程

1. 系统问题排查范围定义 本次交流中描述的故障&#xff0c;主要是指系统级别的故障&#xff0c;对于某个具体的业务功能的故障&#xff0c;不在本次讨论范围内。下面描述的故障定位、排查&#xff0c;主要是指跨模块、跨项目级别的故障的定位、排查&#xff0c;包括软件、硬件…

SpringBoot 3.1.7 集成Sentinel

一、背景 我的项目需要引入限流&#xff0c;降级&#xff0c;熔断框架&#xff0c;由于 Spring Cloud 2022.0.4 已经不再支持 Hystrix&#xff0c;Spring Cloud 提供了替代方案&#xff0c;如 Resilience4j&#xff0c;可以使用它来替换 Hystrix。但是网上搜了一下国内Resilie…

烟火识别视频分析系统的应用-河北消防机器人项目

在当前的智能化、信息化时代背景下&#xff0c;河北省消防部门采纳了一项革命性的技术方案 —— 烟火识别视频分析系统&#xff0c;结合消防机器人的使用&#xff0c;大幅提升了火灾预防与应急处理能力。该项目的核心在于通过高精度的视频监控&#xff0c;实时分析识别潜在的火…

96.乐理基础-记号篇-装饰音记号(四)回音

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;95.乐理基础-记号篇-装饰音记号&#xff08;三&#xff09;波音-CSDN博客 理解了波音&#xff0c;再看回音会很简单。 回音&#xff1a;分两种类型 1.顺回音&#xff0c;样子如图1 2.逆回音&#xff0c;样子看图5…

【多线程的安全问题】synchronized 和 volatile——你必须知道的妙用!

&#x1f4c4;前言&#xff1a;本文的主要内容是讨论个人在多线程编程带来的安全问题的表现、原因以及对应的解决方法。 文章目录 一. 了解多线程安全问题二. 线程不安全的现象及原因&#x1f346;1. 修改共享的数据&#xff08;根本原因&#xff09;&#x1f345;2. 原子性&am…

python期末实训-学生成绩管理系统

pythontkintermatplotlib学生管理系统 一.需求分析 读取学生成绩的excel表格到数据库中将学生成绩导出到excel文件中学生成绩单增删改查与展示学生成绩按学号搜索和按姓名模糊搜素展示班级学生的整体成绩情况导出每位学生的成绩分析图将程序打包成exe 二.系统设计 将表格数…

Ubuntu使用docker-compose安装redis

ubuntu环境搭建专栏&#x1f517;点击跳转 Ubuntu系统环境搭建&#xff08;十三&#xff09;——使用docker-compose安装redis 文章目录 Ubuntu系统环境搭建&#xff08;十三&#xff09;——使用docker-compose安装redis1.搭建文件夹2.docker-compose.yaml配置文件3.redis.co…