news 2025/12/21 17:17:15

二叉搜索树与双向链表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
二叉搜索树与双向链表

目录

基本要求

节点结构

核心算法:中序遍历 + 指针修改

算法思想

递归实现

非递归实现

复杂度分析

时间复杂度:

空间复杂度:


基本要求

这是一个经典的算法问题:将二叉搜索树(BST)转换成一个排序的双向循环链表(或双向链表)。

通常题目要求是:

  1. 双向链表中的节点顺序与二叉搜索树的中序遍历顺序一致(即升序)。
  2. 需要将节点的左右指针分别作为双向链表的前驱(prev)和后继(next)指针。
  3. 有时要求链表是循环的(头尾相连),有时只要求是双向链表。
  4. 原地转换:不能创建新节点,只能调整原有指针

节点结构

class Node { public: int val; Node* left; Node* right; Node(int _val) : val(_val), left(nullptr), right(nullptr) {} };

核心算法:中序遍历 + 指针修改

算法思想

利用BST(二叉搜索树)的中序遍历特性:

  1. 中序遍历BST会按升序访问所有节点
  2. 在遍历过程中,记录前一个访问的节点(prev)
  3. 将当前节点与prev节点双向连接
  4. 遍历完成后,连接头尾节点形成循环

递归实现

class Solution { private: Node* prev = nullptr; // 记录前驱节点 Node* head = nullptr; // 记录链表头节点 // 中序遍历递归函数 void inorderTraversal(Node* curr) { if (!curr) return; // 1. 递归遍历左子树 inorderTraversal(curr->left); // 2. 处理当前节点 if (!prev) { // 第一个节点(最小值),设为头节点 head = curr; } else { // 连接前驱和当前节点 prev->right = curr; curr->left = prev; } // 更新prev为当前节点 prev = curr; // 3. 递归遍历右子树 inorderTraversal(curr->right); } public: Node* treeToDoublyList(Node* root) { if (!root) return nullptr; // 中序遍历并调整指针 inorderTraversal(root); //如果需要转换BST为双向循环链表(不需要删除下面两行代码即可) // 连接头尾形成循环链表 head->left = prev; // 头的前驱指向尾 prev->right = head; // 尾的后继指向头 return head; } };

非递归实现

不使用递归,通过显式栈来模拟中序遍历的过程,在遍历过程中调整指针指向。

class Solution { public: Node* treeToDoublyList(Node* root) { if (!root) return nullptr; Node* prev = nullptr; Node* head = nullptr; stack<Node*> st; Node* curr = root; // 中序遍历(迭代版) while (curr || !st.empty()) { // 左子树入栈 while (curr) { st.push(curr); curr = curr->left; } // 弹出当前节点 curr = st.top(); st.pop(); // 连接节点 if (!prev) { head = curr; // 第一个节点 } else { prev->right = curr; curr->left = prev; } prev = curr; curr = curr->right; // 处理右子树 } //如果需要转换BST为双向循环链表(不需要删除下面两行代码即可) // 形成循环 head->left = prev; prev->right = head; return head; } };

复杂度分析

时间复杂度:

O(n):每个节点被访问一次,n为节点总数

空间复杂度:

O(h),h为树的高度

  • 最坏情况(链状树):O(n)
  • 最好情况(平衡树):O(log n)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/17 4:51:02

Archipack建筑建模插件:从零到精通的终极实战手册

Archipack建筑建模插件&#xff1a;从零到精通的终极实战手册 【免费下载链接】archipack Archipack for blender 2.79 项目地址: https://gitcode.com/gh_mirrors/ar/archipack 核心价值定位 Archipack作为Blender生态中的专业建筑建模插件&#xff0c;重新定义了参数…

作者头像 李华
网站建设 2025/12/17 4:49:58

[鸿蒙2025领航者闯关]人情往来应用开源项目实战

一款基于ArkTS与ArkUI开发的鸿蒙原生应用&#xff0c;为复杂的人际关系提供数字化管理方案 引言&#xff1a;当人情往来遇上数字时代 在中国文化中&#xff0c;人情往来不仅是简单的礼物交换&#xff0c;更是维系人际关系、表达情感的重要方式。然而&#xff0c;随着社交圈的扩…

作者头像 李华
网站建设 2025/12/17 4:46:10

Unitree GO2 ROS2 SDK终极指南:从零开始构建智能机器人系统

Unitree GO2 ROS2 SDK终极指南&#xff1a;从零开始构建智能机器人系统 【免费下载链接】go2_ros2_sdk Unofficial ROS2 SDK support for Unitree GO2 AIR/PRO/EDU 项目地址: https://gitcode.com/gh_mirrors/go/go2_ros2_sdk &#x1f3af; 开篇思考&#xff1a;你的机…

作者头像 李华
网站建设 2025/12/17 4:41:10

学习笔记——线程

线程学习笔记整理一、线程概论基本概念Linux中线程是轻量级的进程&#xff0c;线程属于某个进程作用&#xff1a;实现并发&#xff0c;处理相对耗时任务线程特征进程是系统中最小的资源分配单位线程是系统中最小的执行单位线程关系&#xff1a;进程中&#xff0c;线程与线程是平…

作者头像 李华
网站建设 2025/12/17 4:40:00

PPT AI生成工具真实体验后,结论和想象完全不同

告别办公低效&#xff01;轻竹办公让你的报告高效出彩 每到年终总结的时候&#xff0c;职场人就开始发愁。熬夜改报告成了常态&#xff0c;好不容易搭建好的框架&#xff0c;内容却混乱不堪&#xff0c;设计上更是毫无灵感&#xff0c;做出来的报告美观度严重不足。而且&#…

作者头像 李华
网站建设 2025/12/17 4:34:58

HS2-HF_Patch终极指南:如何快速解锁HoneySelect2完整游戏体验

HS2-HF_Patch终极指南&#xff1a;如何快速解锁HoneySelect2完整游戏体验 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 还在为HoneySelect2的日文界面而烦恼&…

作者头像 李华