剑指 Offer ! ! 36. 二叉搜索树与双向链表

news2024/11/25 4:51:12

剑指 Offer 36. 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:
在这里插入图片描述
在这里插入图片描述
思路:
考虑到二叉搜索树的性质“左树上的结点值小于根节点值,根节点值小于右树上的结点值”,对给定二叉树搜索树做中序遍历即可,期间将“打印操作”(一般的中序遍历二叉树流程中的“打印操作”)换成左右指针的连接操作。

下面是我自己的写法:
listH是双向链表的头节点的前一个结点,可视作“虚拟头节点”;
递归函数f(Node root, Node listH)的参数分别表示:

  • 目前遍历到搜索二叉树上的结点root,
  • 目前双向链表已建成部分的最后结点是listH;

所以,函数内容是 将以root为头节点的子树做中序遍历得到的双向链表 接到 listH后面,并返回 接上之后的结尾结点。
另外,主函数和递归函数内容的设计 保证了 递归函数参数root不为null。

public Node treeToDoublyList(Node root) { // in-order traversal
        if(root==null){return null;}
        Node listH = new Node();
        Node end = f(root,listH);
        Node head = listH.right;
        end.right=head;// 这两句话是看题意得到的,把新双向链表的收尾连起来
        head.left=end;
        return head;
    }
    public Node f(Node root,Node listH){
        if(root.left==null&&root.right==null){// root是叶节点 作为 base case
            Node newNode = new Node(root.val);// 把 newNode 接到 listH的后面
            listH.right = newNode;
            newNode.left=listH;
            return newNode;// new end
        }
        Node end = listH;
        //二叉树的中序遍历: 左
        if(root.left!=null){
            end = f(root.left,listH);// update end
        }
        //二叉树的中序遍历: 中
        Node newNode = new Node(root.val);
        end.right = newNode;
        newNode.left=end;
        end = newNode;// update end
        //二叉树的中序遍历: 右
        if(root.right!=null){
            end = f(root.right,end);// update end
        }
        return end;
    }

LeetCode大佬的写法

巧妙地将head,pre设置成了全局变量;
对二叉树做中序遍历时,pre是双向链表已建成部分的最后一个节点,相当于上面的listH。

Node head,pre;
     public Node treeToDoublyList1(Node root) { // in-order traversal
        if(root==null){
            return null;
        }
       
        dfs(root);
        head.left=pre;
        pre.right=head;
        return head;
     }
     public void dfs(Node cur){
         if(cur==null){return;}
         dfs(cur.left);
    
         if(pre==null){
             head=cur;
             pre=head;
         }else{
             pre.right=cur;
         }
        cur.left=pre;
        pre = cur;
        dfs(cur.right);
     }

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

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

相关文章

Spring Boot 中的 @MessageMapping 注解:原理、用法与示例

Spring Boot 中的 MessageMapping 注解:原理、用法与示例 前言 随着 Web 技术的发展,越来越多的应用程序开始使用 WebSocket 协议来实现实时通信。Spring Boot 提供了对 WebSocket 的支持,其中 MessageMapping 注解是一个常用的注解&#x…

【Keepalived】keepalived部署

1.keepalived二进制安装【Ubuntu20.04】 (1).官网下载二进制源码包 官网: https://keepalived.org/download.html 下载二进制包: wget https://keepalived.org/software/keepalived-2.2.7.tar.gz亦可通过window本地下载并上传 (2).解压文件 [rootu…

[ISO26262]汽车功能安全第二部分:功能安全管理

Road vehicles—Functionalsafety— Part 2: Management offunctionalsafety (ISO 26262-2:2011, MOD) GB/T34590《 道路车辆 功能安全》分为以下部分: TOPS:当前所浏览位置: 随着技术日益复杂、 软件和机电一体化应用不断增加, 来自系统性失效和随机硬件失效的风险逐渐…

蓝桥杯专题-试题版含答案-【两点距离】【字符串替换】【盗梦空间】【素数】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

无向图讲解

讲完了有向图,咱再来讲一下无向图。 直观来说若一个图中每条边都是无方向的,则称为无向图,无向图中的边均是顶点的无序对,无序对通常用圆括号表示。 定义 无向图G=<V,E>,其中: 1.V是非空集合,称为顶点集。 2.E是V中元素构成的无序二元组的集合,称为边集。 解释 直…

如何选择适合的项目管理软件?你需要考虑这些问题

在市场上有很多项目管理软件可供选择&#xff0c;但是如何确定哪种工具最易使用&#xff0c;哪些功能是项目管理必备的呢&#xff1f;在选择项目管理软件之前&#xff0c;你需要考虑以下问题&#xff1a; 项目性质 不同的项目需要不同的管理方法&#xff0c;敏捷管理适用于某…

chatgpt赋能python:Python量化数据来源-介绍

Python量化数据来源 - 介绍 Python在金融量化分析领域中得到了广泛的应用&#xff0c;这部分应用通常被称为Python量化金融。Python量化数据来源是Python量化金融分析的基础&#xff0c;只有良好的数据来源才能保证分析的准确性和有效性。 Python具有以其代码简洁易懂、强大的…

2023年富媒体行业研究报告

第一章 行业概况 富媒体行业是一个快速发展的领域&#xff0c;它涵盖了从视频、音频、动画、互动内容到虚拟现实和增强现实等多种媒体形式。这些媒体形式的共同特点是&#xff0c;它们都能提供比传统文本和静态图像更丰富、更引人入胜的用户体验。 在中国&#xff0c;富媒体行…

深入JavaScript的运行原理

1 深入V8引擎原理 2 JS执行上下文 3 全局代码执行过程 4 函数代码执行过程 5 作用域和作用域链 源代码->抽象语法树->字节码。 其中的字节码在函数执行的时候&#xff0c;由于参数的类型是一样的&#xff0c;所以有优化的机器码&#xff0c;但是如果参数类型发生变化…

昌平GPU集群使用指南 - 非官方版

昌平GPU集群使用指南 - 非官方版 可以在网址导航里看平台的使用指南&#xff0c;本文只是有益补充&#xff01; &#xff08;注&#xff1a;镜像只需要关闭&#xff0c;不需要删除&#xff09; 大致操作流程&#xff1a; 进入protainer&#xff0c;进入containers&#xff0c…

Docker删除镜像,以及导入/导出镜像

总结一下&#xff1a;删除镜像&#xff0c;以及导入/导出镜像的步骤和命令。 一、删除 1.docker rmi remove images。该命令用于删除本地镜像。 镜像通过 指定。如果省略要删除镜像的 tag&#xff0c;默认删除的是 lastest 版本。 比如&#xff1a;docker rmi zookeeper 2.删…

互联网干洗店软件及营销功能介绍

互联网干洗店洗衣洗鞋软件收件、充值、上挂等门店基本功能统统都有&#xff0c;更是支持多店互联互通&#xff0c;连接小程序、公众号&#xff0c;招揽线上生意。 为单店或多门店连锁的经营模式提供一整套的软件系统&#xff0c;包含微信公众号和小程序。 工厂版 为门店中央奢护…

接口测试面试题及答案

Http与Https的区别&#xff1a; Http与Https的区别&#xff1a; HTTP 的URL 以http:// 开头&#xff0c;而HTTPS 的URL 以https:// 开头HTTP 是不安全的&#xff0c;而 HTTPS 是安全的HTTP 标准端口是80 &#xff0c;而 HTTPS 的标准端口是443在OSI 网络模型中&#xff0c;HTTP…

JMeter变量和和属性(4)

这里写目录标题 一、JMeter变量1、使用JMeter变量的作用有&#xff1a;2、定义变量的方式3、引用变量的方式4、引用变量5、案例&#xff1a;切换GreaterWMS的环境6、案例&#xff1a;测试平台登录案例 二、JMeter属性1、JMeter属性特点2、JMeter属性和变量的区别&#xff1a;3、…

9.用python写网络爬虫,完结

前言 这是python网络爬虫的最后一篇给大家做个总结&#xff0c;且看且珍惜把&#xff01; 截止到目前&#xff0c; 前几章本书介绍的爬虫技术都应用于一个定制网站&#xff0c;这样可以帮助我们更加专注于学习特定技巧。而在本章中&#xff0c;我们将分析几个真实网站&#xff…

Python matplotlib 设置多子图、子图间距、边距

Python matplotlib 设置多子图 设置多子图间距 设置多子图边距 1. 方式一 设置一个 2*2 的子图&#xff0c;子图共用X轴&#xff0c;不共用Y轴 import matplotlib.pyplot as pltfig,axes plt.subplots(2,2,figsize(6,6),dpi100,facecolor"w",sharexTrue,shareyFal…

基于Java+Swing+Mysql员工信息管理系统

基于JavaSwingMysql员工信息管理系统 一、系统介绍二、功能展示1.主页2.查询员工信息3.删除员工信息 三、数据库四、其他系统实现五、获取源码 一、系统介绍 该系统实现了查看员工列表、查询员工信息、删除员工信息 运行环境&#xff1a;eclipse、idea、jdk1.8 二、功能展示…

【Java】Java核心 78:Git 教程(1)Git 概述

文章目录 01.GIT概述目标内容小结 02.GIT相关概念目标内容小结 01.GIT概述 Git是一个分布式版本控制系统&#xff0c;常用于协同开发和版本管理的工具。它可以跟踪文件的修改、记录历史版本&#xff0c;并支持多人协同工作。通过Git&#xff0c;你可以轻松地创建和切换分支、合…

Redis最基础内容

文章目录 一、Redis简介1、特点&#xff1a;2、优势 二、启动Redis三、数据类型0、通用命令1、String(字符串)2、Hash类型3、List类型4、Set&#xff08;集合&#xff09;5、zset(sorted set&#xff1a;有序集合)6、各个数据类型使用场景 四、SpringDataRedis1、RedisTemplate…

Yolov5优化: 多分支卷积模块RFB,扩大感受野提升小目标检测精度

目录 1.RFB-Net介绍 2. RFB引入到yolov5 2.1修改commmon.py 2.2 修改yolo.py 2.3 yolov5s_REF.yaml 1.RFB-Net介绍 论文&#xff1a;https://arxiv.org/pdf/1711.07767.pdf 代码&#xff1a;https://github.com/ruinmessi/RFBNet 受启发于人类视觉的Receptive Fields结构&…