C++ 耐心排序2025年2月11日 | 阅读 9 分钟 排序算法是计算机科学的基础,因为它们是许多应用程序和系统的基础。然而,最有效的排序技术之一是耐心排序,因为它基于名为 Patience 或 Solitaire 的纸牌游戏,策略非常巧妙。耐心排序不像快速排序或归并排序那样受欢迎,但其效率接近,时间复杂度为O(nlogn)。 该算法之所以被称为耐心排序,是因为它借鉴了 Patience 纸牌游戏,在该游戏中,我们需要将一副牌按多堆排序。这种排序方法非常有趣,因为它模仿了实际的游戏动作,这些动作是基于牌的排序,而且孩子们喜欢学习。尽管耐心排序是一个理论概念,并未用于实际排序数据,但其简单的方法以及解决相关问题的能力(例如寻找最长递增子序列的长度)使其成为程序员工具箱中的一个附加工具。 在这篇博文中,我们将剖析耐心排序的核心思想及其工作流程。我们还将介绍如何在 C++ 中使用耐心排序,并概述如何在实践中应用它;我们还将重点介绍其时间和空间复杂度。在本文的最后,读者将掌握关于耐心排序如何工作及其使用可能性的充分信息。 理解概念本质上,耐心排序是一种算法,它模仿了 Patience 纸牌游戏的过程,在该游戏中,牌被分成堆。主要思想是生成多个堆,使得每个堆中的元素从上到下都是递增的。排序通过根据一组定义的标准将输入数组的每个元素归入其中一个堆中,然后合并这些堆来得到排序后的数组来实现。 堆的创建耐心排序的第一个过程是将对象分成堆。数组中的每个成员都被放入一个堆中,其方式是确保所有堆都包含递增顺序的元素。将元素放入堆的规则如下:
合并堆在所有元素都已排序并放入堆之后,下一步是合并所有这些堆以形成排序后的数组。合并技术包括遍历堆栈,并在每一步中,从每个堆的顶部选择最小的元素并将其放入排序后的数组中。这可以使用最小堆(优先队列)来完成,并且需要 O(m) 的时间。 最小堆使我们能够以最短的时间找到并提取堆顶的最小元素。每次从堆中取出最小的元素时,都会将同一堆中的下一个元素插入到该位置。此过程一直持续到所有堆都变空,并且排序后的数组已用递增顺序的元素形成。 耐心排序的分步算法耐心排序是一种基于 Patience 纸牌游戏的有趣算法。该算法通过创建和合并 n 个元素堆来工作,并且排序数组通常保持有效,具有O(n log n)的时间复杂度。这是对已分析的分步算法的清晰详细的理论描述。 步骤 1:初始化当算法开始时,它将堆列表初始化为一个空列表。每个堆最终将包含从堆顶部到底部按递增顺序排列的元素。此时,没有可供处理的元素,因此也没有要组织的堆。 步骤 2:创建堆算法的主要步骤在一个主循环中进行,在此期间,输入数组的每个元素都必须放置到正确的堆中。此过程的详细操作如下: 遍历元素 如果要遍历输入数组中的所有元素,则遍历过程如下: 查找正确的堆 对于每个元素,查找最左边的堆,该堆的顶部元素(牌)大于或等于当前元素。这有助于保持每个堆的顺序,使得堆按升序排序。
放置元素
步骤 3:合并堆
插入初始元素
提取和替换 以同样的方式,如果堆中还有另一个元素属于该特定堆,则将提取的元素替换为下一个元素。这可以保持堆的大小不变,并确保每个元素都会在某个时候被纳入该过程。 继续进行此提取和替换过程,直到从堆中获得最后一个项目。每次提取和替换操作都确保堆的最小元素始终位于堆的顶部,以便正确排序。
步骤 4:结果在所有合并完成后,来自堆的元素将合并到数组中并按升序排序。该算法保证程序的输出与函数调用相比是已排序的元素。 代码实现输出 Enter the number of elements: 8 Enter the elements: 6 3 8 1 5 2 7 4 Original array: 6 3 8 1 5 2 7 4 Sorted array: 1 2 3 4 5 6 7 8 耐心排序的优点
耐心排序的缺点
下一个主题C++ 中的伯特兰公理 |
概述 C++ 反射过程与应用程序程序在执行期间反射和修改自身内部结构和行为的能力有关。与包含 Java 或 C# 等内置反射的语言不同,C++ 不支持此功能......
7 分钟阅读
在 C++ 中,函数重载和函数模板是用于提高程序可重用性的灵活功能。然而,它们针对不同的目标并在不同的上下文中应用。本文通过示例探讨函数重载和函数模板以及如何使用它们。什么是……
阅读 4 分钟
CSV 文件格式,即“逗号分隔值”,通常用于存储和交换已使用的表格数据。CSV 文件中的数据以纯文本形式组织成行和列。CSV 文件由组织成行和列的纯文本数据组成。每行代表一个...
阅读 4 分钟
在本文中,我们将讨论 C++ 中的缓存友好代码及其工作原理和几个示例。什么是?旨在最大限度地提高内存访问模式以充分利用 CPU 缓存(用于保存频繁请求数据的快速、紧凑的内存)的编程称为……
阅读 4 分钟
引言:在遍历二叉树时,涉及以系统化的顺序访问所有给定节点。逆时针螺旋遍历是遍历二叉树的唯一方法。这种遍历从根节点开始,然后到最左边的叶节点,接着……
11 分钟阅读
某些数学概念是编程中的绝佳示例,“裸数”(nude numbers)就是其中之一。即使这个术语很有趣,它也很深入,并且具有数学优雅的本质,以简洁的语言写成。本文探讨了一个想法,即...
阅读 4 分钟
C++ 是一种强大而复杂的编程语言,它为系统和应用程序级别的编程提供了各种工具。在其众多特性中,C++ 提供了
阅读 15 分钟
什么是自数?自数是数学中的一种特殊数字。它不能通过将一个数字与其数字之和相加来生成。换句话说,当你应用一个称为“生成器”的特定函数时,没有其他数字会产生它……
11 分钟阅读
在 C++ 中,char 是一种数据类型,用于表示单个字符,例如 'A' 或 '5'。有时,我们可能想将此字符转换为 int。在处理数字或想知道 ASCII 值时,这是一项常见任务...
阅读 6 分钟
在本文中,我们将讨论如何在 C++ 中生成随机双精度数。在 C++ 中,头文件提供了许多随机数生成函数,可用于生成随机双精度数。std::random_device 类,它充当种子生成器,以及 std::mt19937 类,它是...(省略)
阅读 4 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India