C++ 中每个节点的下一个右侧指针填充2025 年 2 月 11 日 | 阅读 13 分钟 在二叉树的每个节点中填充下一个右侧指针是一个经典的计算机科学问题,它涉及增强树的结构以方便某些类型的遍历和操作。当需要进行逐层操作时,这个问题尤其相关,例如在广度优先搜索 (BFS) 中,我们需要一起处理同一级别的节点。 在许多与树相关的算法和应用中,节点必须逐层遍历或连接,以便每个节点都可以直接访问同一级别的右邻节点。这在广度优先搜索 (BFS)、层序遍历以及各种图算法等场景中特别有用。 填充二叉树中每个节点的下一个右侧指针的问题涉及为每个节点添加一个名为 next 的指针。这个 next 指针应该指向当前节点同一级别上紧邻的右侧节点。如果不存在这样的节点,则 next 指针应设置为 nullptr。 这项任务在计算机网络中有实际应用,其中同一级别的节点可能代表需要相互通信的设备或服务器。它也用于图形用户界面,其中同一级别的元素需要链接起来以便高效导航。 方法一:使用队列的层序遍历在层序遍历中,节点从左到右逐层访问。通过使用队列,我们可以保持遍历树时节点的顺序。在每个级别,我们将每个节点的 next 指针设置为队列中紧跟其后的节点。此过程一直持续到当前级别的所有节点都处理完毕。 使用队列进行层序遍历是解决在二叉树的每个节点中填充下一个右侧指针问题的直接方法。此方法利用广度优先搜索 (BFS) 技术逐层遍历树,确保同一级别的所有节点都通过其 next 指针连接起来。以下是在 C++ 中的详细解释和实现。 程序输出 Next pointers in the binary tree: 1 -> nullptr 2 -> 3 -> nullptr 4 -> 5 -> 6 -> 7 -> nullptr 说明任务是修改二叉树,使得每个节点的 next 指针指向同一级别的直接右侧节点。这允许逐层高效地遍历树,从而促进层序遍历或其他需要同一级别节点间连接的算法。
复杂度分析时间复杂度 提供的解决方案中的主要方法是 connect,它使用队列通过广度优先搜索 (BFS) 方法逐层遍历二叉树并建立下一个指针。以下是时间复杂度的详细分解: 遍历节点 二叉树中的每个节点都入队一次,出队一次。 因此,对于一个有 n 个节点的二叉树,入队和出队操作的次数是 n。 内部循环执行 在二叉树的每个级别,我们处理该级别存在的所有节点。所有级别的节点数之和等于树中的总节点数 n。 设置 next 指针并入队其子节点(如果存在)是每个节点的常数时间操作。由于入队和出队都是 O(1) 操作,并且每个节点都只执行这些操作一次,因此处理所有节点的总体时间复杂度为 O(n)。 空间复杂度 解决方案的空间复杂度由在任何给定时间用于在队列中存储节点的最多空间决定。以下是详细分析: 队列空间 队列逐层存储节点。在任何级别中队列中存储的节点数最多对应于二叉树的最大宽度。 在最坏情况下,对于一个完全平衡的二叉树,最后一个级别(叶子节点)的最大节点数约为 n/2。 最大宽度 对于高度为 h 的平衡二叉树,最后一个级别包含多达 2^h 个节点。 给定高度为 h 的二叉树对于平衡树是 log(n)(基数为 2),在最坏情况下的最大宽度是:然而,对于大多数实际场景来说,这是一个过于悲观的估计。通常,对于平衡二叉树,队列所需的空间与叶子节点的数量成正比,即 O(n/2) = O(n)。 辅助空间 除了队列使用的空间外,该算法还使用固定量的额外空间用于 levelSize 和循环计数器等变量。 考虑到存储平衡树中最多 n/2 个节点到队列中的最坏情况,以及辅助变量使用的固定空间,总体空间复杂度为 O(n)。 方法二:恒定空间迭代方法填充二叉树中每个节点的下一个右侧指针的恒定空间迭代方法是一种高效的方法,它避免使用额外的空间,如队列或其他数据结构,来达到相同的目标。此方法利用二叉树的现有结构及其 next 指针来逐层遍历和连接节点。 在二叉树中,每个节点最多可以有两个子节点:一个左子节点和一个右子节点。任务是连接每个节点与同一级别内的直接右邻节点,为每个级别形成一个链表状结构。这通常通过层序遍历来实现,其中节点从左到右逐层处理。 程序输出 Next pointers in the binary tree: 1 -> nullptr 2 -> 3 -> nullptr 4 -> 5 -> 6 -> 7 -> nullptr 说明提供的代码旨在连接二叉树中每个节点的 next 指针,使每个节点指向同一级别内的直接右邻节点。这是使用恒定空间迭代方法实现的,避免了像队列这样的额外空间。
复杂度分析时间复杂度 提供的解决方案中的主要方法是 connect,它使用恒定空间迭代方法逐层遍历二叉树并建立下一个指针。以下是时间复杂度的详细分解: 遍历节点 二叉树中的每个节点都被访问一次。对于一个包含 n 个节点的二叉树,每个节点以 O(1) 的常数时间进行处理,以设置 next 指针并将它们移动到下一个节点或级别。因此,遍历涉及访问 n 个节点。 内部循环执行 对于二叉树的每个级别,我们处理该级别存在的所有节点。所有级别的节点数之和等于树中的总节点数 n。对于每个节点,设置 next 指针和移动指针是常数时间操作。 由于每个节点的遍历和指针设置都是 O(1) 操作,并且每个节点都只执行这些操作一次,因此处理所有节点的总体时间复杂度为 O(n)。 空间复杂度 解决方案的空间复杂度由算法所需的最多额外空间决定。以下是详细分析: 虚拟节点和尾部指针 该算法使用一个虚拟节点和一个尾部指针来管理下一级别的连接。这些指针不依赖于树的大小,因此其空间使用是恒定的 O(1)。 当前指针 当前指针用于遍历当前级别的节点。与虚拟节点和尾部指针一样,此指针也独立于树的大小,因此空间使用是恒定的 O(1)。 无额外数据结构 与使用队列或其他数据结构的方法不同,此方法不需要额外的节点存储空间。因此,它避免了与此类数据结构相关的 O(n) 空间复杂度。 辅助空间 除了虚拟节点、尾部指针和当前指针使用的空间外,该算法还为循环计数器等辅助变量使用固定量的额外空间。考虑到所有这些因素,总体空间复杂度为 O(1)。 下一个主题C++ 中的贝塞尔插值 |
C++17,也称为 ISO/IEC 14882:2017,是 C++ 编程语言标准的第三次重大更新。官方发布日期是 2017 年 12 月。C++17 通过引入新的亮点、补充和增强来扩展 C++11 和 C++14 的方面。主要目标是...
阅读 4 分钟
在本文中,我们将讨论 C++ 中超图的实现。但在进入其实现之前,我们必须了解超图。什么是超图?超图是一种独特的图。它允许单个边连接两个或多个...
阅读 3 分钟
在本文中,我们将讨论如何在 C++ 中查找哈希冲突的索引,并提供几个示例。问题陈述:假设我们有一个数字 a 和一个包含 n 个元素的数组 P。有一个带有 'a' 个桶的哈希表...
5 分钟阅读
简介:旋转排序数组在计算机科学和算法中非常有趣。旋转排序数组是曾经是已排序数组但已围绕某个未知旋转点旋转的数组。旋转可以是顺时针或逆时针方向。旋转的主要问题...
阅读 6 分钟
在数字方面,斐波那契数列和佩尔数数列具有相似的递推关系。佩尔数由递推关系定义:p(n)=2*p(n-1)+p(n-2),其初始值为 p(0)=0 & p(1)=1。这些是前几个佩尔数:0、1、2、5、12、29、70、...
阅读 4 分钟
在本文中,我们将讨论 C++ 中的 std::defer_lock_t、std::try_to_lock_t 和 std::adopt_lock_t 的语法和示例。这三种标签类型在 C++ 中可用,即 std::defer_lock_t、std::try_to_lock_t 和 std::adopt_lock_t。这些标签类型主要与 std::unique_lock 和 std::lock_guard 结合使用,以定义锁定...
5 分钟阅读
C++ 程序使用用户提供的包含两个浮点值(表示变量 X 和 Y)的 vector 作为输入来计算皮尔逊相关系数。皮尔逊相关系数用于测量两个变量之间的线性关系。它通常取值介于 -1 之间……
5 分钟阅读
正整数,例如具有特定除数关系的成对正整数的条目,被称为婚约数或准亲和数。一对数 a 和 b 被认为是婚约数,如果满足以下条件:σ(a) - a...
阅读 12 分钟
在现代 C++(从 C++20 开始)中,通过三向比较的概念(通常称为宇宙飞船运算符 (<=>))引入了一种强大而直观的比较对象和值的方法。此运算符允许您比较两个对象并获得一个单一值...(省略)
阅读 8 分钟
在本文中,我们将讨论如何检查一个数字是否是等位数字。在此之前,让我们先了解一下什么是等位数字。什么是等位数字?一个 n 位数被称为等位数字,如果其质因数分解中的数字数量...
7 分钟阅读
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India