【LeetCode刷题(数据结构与算法)】:将二叉搜索树转化为排序的双向链表

在这里插入图片描述
将一个 二叉搜索树 就地转化为一个 已排序的双向循环链表
对于双向循环列表,你可以将左右孩子指针作为双向循环链表的前驱和后继指针,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点
特别地,我们希望可以 就地 完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中最小元素的指针
示例 1:
输入:root = [4,2,5,1,3]
在这里插入图片描述

输出:[1,2,3,4,5]
解释:下图显示了转化后的二叉搜索树,实线表示后继关系,虚线表示前驱关系
在这里插入图片描述
示例 2:
输入:root = [2,1,3]
输出:[1,2,3]
示例 3:
输入:root = []
输出:[]
解释:输入是空树,所以输出也是空链表
示例 4:
输入:root = [1]
输出:[1]
如何遍历树
遍历树的一般策略有两种:
深度优先搜索 (DFS) 在这种策略中,我们将 深度 作为优先级,因此我们从根节点开始,一路搜索到某个叶子节点,然后返回根节点寻找另一条分支。DFS 策略可以进一步区分为 前序,中序 和 后序,这取决于根节点、左节点和右节点之间的相对顺序
广度优先搜索 (BFS) 我们按照高度的顺序,从上到下扫描整棵树 高层级的节点会比低层级的节点先被访问 在下面的图像中,节点按照你访问它们的顺序进行编号,请按照 1-2-3-4-5 的顺序比较不同的策略
在这里插入图片描述
这个问题是以教科书递归方式实现 DFS 中序遍历,因为它要求就地(in-place)操作

方法:递归

算法 标准的中序递归遵循 左 -> 节点 -> 右 的顺序,其中 左 和 右 部分是递归调用,而 节点 是所有处理过程的执行场所。 处理在这里基本上是将前一个节点与当前节点相连,并记录到目前为止新双向链表中的最大节点,亦即最后一个节点
再多一个细节:需要保留第一个,即最小的节点,以封闭双向链表的环。 这是算法的步骤:
初始化 first 和 last 节点为 null
调用标准的中序递归 helper(root) :
如果节点不为 null:
调用左子树的递归 helper(node.left)
如果 last 节点不为 null,将 last 和当前 node 节点连接起来
若 else,则初始化 first 节点
将当前节点标记为最后一个节点:last = node
调用右子树的递归 helper(node.right)
将首尾两个节点连接起来,封闭 DLL 环,然后返回 first 节点
在这里插入图片描述
在这里插入图片描述

/*
// Definition for a Node.
struct Node {int val;struct Node* left;struct Node* right;
};
*/
void helper(struct Node*node,struct Node**first,struct Node**last)
{if(node){helper(node->left,first,last);if(*last){(*last)->right=node;node->left=*last;}else{*first=node;}*last=node;helper(node->right,first,last);}
}
struct Node* treeToDoublyList(struct Node *root) {struct Node*first=NULL;struct Node*last=NULL;if(root==NULL){return root;}else{helper(root,&first,&last);last->right=first;first->left=last;}return first;
}

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

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

相关文章

LAXCUS分布式操作系统是怎么实现的?

一直有网友要求讲讲LAXCUS分布式操作系统是怎么实现的,其实LAXCUS分布式操作系统的设计研发,涉及各种基础技术和底层架构,研发过程很漫长,一直在坚持,实现过程也非常复杂,尤其重要的是要保证运行过程&#…

前端 TS 快速入门之二:接口

1. 接口有什么用 通过 interface 定义接口。 检测对象的属性,不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。 interface IPerson {name: string;age: number; } function say(person: IPerson): void {console.log(my name is ${pers…

Elasticsearch 8.9 Master节点处理请求源码

大家看可以看ElasticSearch源码:Rest请求与Master节点处理流程(1) 这个图非常好,下午的讲解代码在各个类和方法之间流转,都体现这个图上 一、Master节点处理请求的逻辑1、节点(数据节点)要和主节点进行通讯&#xff0…

C语言常量

常量的概念 常量: 在程序运行期间不可以该改变的量 作用: 用于记录程序中不可更改的数据 常量的五种表现形式 语法: 1、数值常量(整数型常量(整数)、实数型常量(小数)&#xff09…

C++中的智能指针:更安全、更便利的内存管理

在C++编程中,动态内存管理一直是一个重要且具有挑战性的任务。传统的C++中,程序员需要手动分配和释放内存,这往往会导致内存泄漏和悬挂指针等严重问题。为了解决这些问题,C++11引入了智能指针(Smart Pointers)这一概念,它们是一种高级的内存管理工具,可以自动管理内存的…

【数据结构】线性表(四)双向链表的各种操作(插入、删除、查找、修改、遍历打印)

目录 线性表的定义及其基本操作(顺序表插入、删除、查找、修改) 四、线性表的链接存储结构 1. 单链表 2. 循环链表 3. 双向链表 a. 双向链表节点结构 b. 创建一个新的节点 c. 在链表末尾插入节点 d. 在指定位置插入节点 e. 删除指定位置的节点…

LeetCode 2172. 数组的最大与和【状压DP,记忆化搜索;最小费用最大流】2392

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

Juniper防火墙SSG-140 session 过高问题

1.SSG-140性能参数 2.问题截图 3.解决方法 (1)通过telnet 或 consol的方法登录到防火墙; (2)使用get session 查看总的session会话数,如果大于300 一般属于不正常情况 (3)使用get…

Python的编辑器VScode中文设置和Hello World

Python的编辑器 个人比较常用的用于Python开发的编辑器是VScode,大概的原因应该是免费,且便于项目文件的管理。 VScode中文设置插件及使用方法 VScode下载安装好之后,可以在软件左侧的“扩展”中搜索安装一些插件,用于辅助开发…

H5随机短视频滑动版带打赏源码,可封装APP软件或嵌入式观看

H5随机短视频滑动版带打赏源码,可封装APP软件或嵌入式观看,网站引流必备源码! 数据来源抖音和快手官方短视频链接,无任何违规内容!可自行添加广告等等! 手机端完美支持滑动屏幕观看(向上或向右…

思维模型 上瘾模型(hook model)

本系列文章 主要是 分享 思维模型,涉及各个领域,重在提升认知。你到底是怎么上瘾(游戏/抖音)的?我们该如何“积极的上瘾”?让我们来一切揭晓这背后的秘密。 1 上瘾模型的应用 1.1上瘾模型的积极应用 1 学…

RT-Thread学习笔记(三):线程管理

线程管理 线程管理相关概念什么是时间片轮转调度器锁线程运行机制线程的五种状态 动态和静态创建线程区别动态和静态创建线程优缺点RT-Thread动态线程管理函数动态创建线程动态删除线程 RT-Thread静态线程管理函数静态创建线程 线程其他操作线程启动线程延时获得当前执行的线程…

四、基本组件

1. Designer设计师 Designer程序是Qt官方推出的专为设计人员使用的UI设计工具,程序员可以使用此工具大幅降低UI设计的代码量。 Designer设计文件的格式是.ui,需要配合同名的头文件与源文件使用。.ui文件通常被称为界面文件,其内部是xml语法的…

微机原理:汇编语言语句类型与格式

文章目录 壹、语句类型1、语句分类2、常用伪代码和运算符2.1数据定义伪指令2.1.1字节定义伪指令DB(8位)2.1.2字定义伪指令DW(16位)2.1.3双字节伪指令DD2.1.4 多字节定义DF/DQ/DT(了解) 2.2 常用运算符2.2.1…

【数据库】SQL 过滤数据

过滤数据 简单过滤where 子句操作符检查单个值范围值检擦空值检查 高级过滤多个过滤条件求值顺序IN 操作符NOT 操作符 在 s q l sql sql 语句中,通过 WHERE 子句指定搜索条件进行过滤。 简单过滤 包含:WHERE,BETWEEN,IS NULL&a…

面向对象与面向过程讲解

目录 简介 面向过程编程(Procedural Programming) 什么是面向过程编程? 特点: 面向对象编程(Object-Oriented Programming) 什么是面向对象编程? 特点: 面向对象 vs. 面向过程…

学习人工智能

在线课程 优达学城 当斯坦福大学讲师 Sebastian Thrun 和 Peter Norvig 将他们的课程“人工智能概论”免费放到网上时,Udacity 开始了在线学习的实验。从那时起,它就受到了巨大的欢迎(来自 190 多个国家的 160,000 名学生)&#x…

[java进阶]——异常详解,try catch捕获异常,抛出异常

🌈键盘敲烂,年薪30万🌈 目录 一、异常的体系结构 二、处理异常的本质 三、异常处理的三种方式 3.1虚拟机jvm处理(默认) 3.2 try catch捕获异常 3.3抛出异常 3.4finally关键字 四、自定义异常 五、总结 一、异常的体系结构 分析&#…

【uniapp】proxy 代理切换至线上测试地址调试接口

本地测试地址形如:http://192.168.124.x:xxxx 线上测试地址形如:https://xxxx.xxxx.com 使用线上地址之后需要修改配置项 secure 为 true const constant require(./src/utils/constant) module.exports {devServer: {proxy: {/api: {target: constan…

Node-EventEmitter的用法

题记 EventEmitter的用法,以下是详细过程和代码。 Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.readStream 对象会…