快速排序与堆排序

2023-12-29

快速排序和堆排序都进行就地排序。哪个更好?首选哪种应用和案例?


堆排序是 O(N log N) 保证的,这比快速排序中最坏的情况要好得多。堆排序不需要更多内存来让另一个数组像合并排序那样放置有序数据。那么为什么商业应用程序坚持使用快速排序呢?与其他实现相比,快速排序有何特别之处?

我自己测试了这些算法,发现快速排序确实有一些特别之处。它运行速度很快,比Heap和Merge算法快得多。

快速排序的秘密是:它几乎不进行不必要的元素交换。交换很费时间。

使用堆排序,即使所有数据都已排序,您也将交换 100% 的元素来对数组进行排序。

如果使用合并排序,情况会更糟。您将把 100% 的元素写入另一个数组中,然后将其写回到原始数组中,即使数据已经排序。

使用快速排序,您不会交换已经订购的内容。如果你的数据是完全有序的,那么你几乎不需要交换任何东西!尽管对于最坏的情况有很多争论,但在主元的选择上稍加改进,除了获取数组的第一个或最后一个元素之外,都可以避免这种情况。如果从第一个、最后一个和中间元素之间的中间元素得到一个主元,就足以避免最坏的情况。

Quicksort的优越之处不是最坏的情况,而是最好的情况!在最好的情况下,你会进行相同数量的比较,好吧,但你几乎什么也不交换。在一般情况下,您会交换部分元素,但不是全部元素,如堆排序和合并排序。这就是快速排序的最佳时机。更少的交换,更快的速度。

下面在我的计算机上用 C# 实现,在发布模式下运行,使用中间枢轴比 Array.Sort 快 3 秒,使用改进枢轴则比 Array.Sort 快 2 秒(是的,获得良好枢轴需要一定的开销)。

static void Main(string[] args)
{
    int[] arrToSort = new int[100000000];
    var r = new Random();
    for (int i = 0; i < arrToSort.Length; i++) arrToSort[i] = r.Next(1, arrToSort.Length);

    Console.WriteLine("Press q to quick sort, s to Array.Sort");
    while (true)
    {
        var k = Console.ReadKey(true);
        if (k.KeyChar == 'q')
        {
            // quick sort
            Console.WriteLine("Beg quick sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
            QuickSort(arrToSort, 0, arrToSort.Length - 1);
            Console.WriteLine("End quick sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
            for (int i = 0; i < arrToSort.Length; i++) arrToSort[i] = r.Next(1, arrToSort.Length);
        }
        else if (k.KeyChar == 's')
        {
            Console.WriteLine("Beg Array.Sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
            Array.Sort(arrToSort);
            Console.WriteLine("End Array.Sort at " + DateTime.Now.ToString("HH:mm:ss.ffffff"));
            for (int i = 0; i < arrToSort.Length; i++) arrToSort[i] = r.Next(1, arrToSort.Length);
        }
    }
}

static public void QuickSort(int[] arr, int left, int right)
{
    int begin = left
        , end = right
        , pivot
        // get middle element pivot
        //= arr[(left + right) / 2]
        ;

    //improved pivot
    int middle = (left + right) / 2;
    int
        LM = arr[left].CompareTo(arr[middle])
        , MR = arr[middle].CompareTo(arr[right])
        , LR = arr[left].CompareTo(arr[right])
        ;
    if (-1 * LM == LR)
        pivot = arr[left];
    else
        if (MR == -1 * LR)
            pivot = arr[right];
        else
            pivot = arr[middle];
    do
    {
        while (arr[left] < pivot) left++;
        while (arr[right] > pivot) right--;

        if(left <= right)
        {
            int temp = arr[right];
            arr[right] = arr[left];
            arr[left] = temp;

            left++;
            right--;
        }
    } while (left <= right);

    if (left < end) QuickSort(arr, left, end);
    if (begin < right) QuickSort(arr, begin, right);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速排序与堆排序 的相关文章

  • j2me中读取文件内容

    我有一个如下所示的文件 OrderNo id name count Format 1 AA1 sdflsdfsdfd 12 01 2 AB2 asdaewqrftr 13 02 3 AA3 aerefytrsu 12 01 我想读取这个文件
  • 如何使用networkx删除有向图中的所有相关节点?

    我不确定我的问题的正确术语是什么 所以我只会解释我想做的事情 我有一个有向图 删除节点后我希望所有独立相关的节点也被删除 这是一个例子 假设我删除节点 11 我希望节点 2 也被删除 在我自己的示例中 它们将是 2 以下的节点 现在也必须删
  • DataGridView小数不排序

    好吧 我有一个 DataGridView 它的数据绑定如下 dataGridViewChartOre AutoGenerateColumns false dataGridViewChartOre DataSource xml GetOreC
  • Python Pandas 按列对多索引进行排序,但保留树结构

    使用 pandas 0 20 3 我尝试按列 D 对数据帧的 n 个多级进行排序 其中的值 降序 以便维护组的层次结构 输入示例 D A B C Gran1 Par1 Child1 3 Child2 7 Child3 2 Par2 Chil
  • 将 n 个可变高度图像拟合为 3 个(相似长度)列布局

    我正在寻找类似于的 3 列布局piccsy com http piccsy com 给定许多宽度相同但高度不同的图像 有什么算法可以对它们进行排序以使列长度的差异最小 最好使用 Python 或 JavaScript 非常感谢您提前的帮助
  • n的渐近增长选择下限(n/2)

    如何找到 n select Floor n 2 的渐近增长 我试过 使用扩展并得到它等于 n n 1 floor n 2 1 n floor n 2 知道我该如何从那里去吗 感谢任何帮助 更喜欢提示而不是答案 我同意上面的答案 但想提供更多
  • 查找数组中 2 个缺失数字的最快方法

    这个问题的存在只是出于纯粹的好奇心 不是作业 找到在数组 1 n 中找到两个缺失数字的最快方法 因此 在相关帖子中 查找数字数组中缺失数字的最快方法 https stackoverflow com questions 2113795 qui
  • CSR 矩阵 - 矩阵乘法

    我有两个方阵A and B 我必须转换B to CSR Format并确定产品C A B csr C 我在网上找到了很多关于CSR 矩阵 向量乘法 http www mathcs emory edu cheung Courses 561 S
  • 有没有办法在 C 中按多个变量对结构进行排序?

    我必须编写一个对数组中的结构进行排序的函数 结构是 define MAX USERNAME LENGTH 16 typedef struct char username MAX USERNAME LENGTH unsigned int ri
  • 找到将一个数字转换为另一个数字的最小移动次数的算法

    假设我们有两个正整数 a 和 b 每次移动我们都可以将 a 除以 2 但前提是 a 是偶数 将 a 乘以 2 或者将 a 加 1 将a变为b需要多少步 找到一个直接公式或一种有效的算法 即以对数时间运行的算法 我取得的一些进展 我们可以把它
  • Python Pandas 根据另一列的总计从另一个数据帧中选择值

    我下面有一个 DataFrame 但我需要根据取消和订单列从每个代码中选择行 假设代码 xxx 的阶数为 6 1 5 1 阶数为 11 我需要一种算法 可以选择满足总共 11 行的行 阶数为 6 5 如果没有行匹配 则选择最接近的 id 并
  • 找到一个恰好出现了 N/2 次的数字

    这是我的面试问题之一 给定一个包含 N 个元素的数组以及元素出现的位置正好 N 2次 其余 N 2 个元素是unique 您如何找到运行时间更好的元素 请记住 元素未排序 您可以假设 N 是偶数 例如 input array 10 2 3
  • 按字母顺序对列表进行排序

    我有以下课程 class Detail public Detail details new List
  • 我该如何解决? KnapSack - 值完全相同,但每个对象都有三个权重

    我在解决我的练习时遇到问题 我读到了动态规划和算法 我认为我的练习是 特定背包问题 我用暴力法解决了它 但我无法用动态规划解决它 我有一艘重300吨的船 背包 有些晶体本身含有 3 种物质 X Y Z 每种物质都有重量 并且所有晶体都具有相
  • 基于数组对列表进行排序

    我正在尝试根据字符串数组对自定义列表进行排序 但我失败得很惨 例如它根本没有对列表进行排序 Public class CrateOrder public int Id get set public string Name get set p
  • 沿着长数据序列在固定大小的移动窗口中查找中值

    给定一个数据序列 可能有重复项 一个固定大小的移动 窗口 从数据开始处每次迭代时移动窗口 序列 使得 1 从窗口中删除最旧的数据元素并添加新数据 元素被推入窗口 2 求每次移动时窗口内数据的中位数 以下帖子没有帮助 有效地找到随机序列的中值
  • 竞争性编码 - 以最低成本清除所有级别:未通过所有测试用例

    当我遇到这个问题时 我正在一个竞争性编码网站上解决问题 问题指出 游戏中有 N 个关卡和 M 种可用武器 等级编号从 0 到 N 1 武器编号从 0 到 M 1 您可以按任意顺序清除这些级别 在每个关卡中 需要这些 M 武器的某些子集才能通
  • 线性问题和非线性问题之间的区别?点积和核技巧的本质

    核技巧将非线性问题映射为线性问题 我的问题是 1 线性问题和非线性问题的主要区别是什么 这两类问题的差异背后的直觉是什么 核技巧如何帮助在非线性问题上使用线性分类器 2 为什么点积在这两种情况下如此重要 Thanks 当人们说到分类问题的线
  • 二分查找问题? [复制]

    这个问题在这里已经有答案了 可能的重复 实施二分查找有哪些陷阱 https stackoverflow com questions 504335 what are the pitfalls in implementing binary se
  • ElasticSearch - 定义自定义字母顺序进行排序

    我正在使用 ElasticSearch 2 4 2 通过 Java 的 HibernateSearch 5 7 1 Final 我在字符串排序方面遇到问题 我的应用程序的语言有变音符号 它们有特定的字母顺序 订购 例如 直接在之后L 追随O

随机推荐

  • JFrame 中的图像相互覆盖,而不是相互显示两个图像[重复]

    这个问题在这里已经有答案了 public class Board extends JFrame public void bd JFrame frame new JFrame JLabel background1 new JLabel new
  • Cassandra 中用于差异比较的 Merkle 树

    我正在读一本document http docs datastax com en cassandra 3 0 cassandra operations opsRepairNodesManualRepair html关于卡桑德拉的修复 它说
  • Android studio 1.1.0 设置 minifyEnabled true 导致应用程序出现问题

    这是我的 gradle build 文件 defaultConfig minSdkVersion 15 targetSdkVersion 21 versionCode 2 versionName 1 0 buildTypes release
  • 如何在 Python 中对 URL 参数进行百分比编码?

    If I do url http example com p urllib quote query 它不编码 to 2F 破坏 OAuth 规范化 它不处理 Unicode 它会抛出异常 有更好的图书馆吗 From Python 3 文档
  • 如何使“setup.py bdist_egg”忽略特定源文件?

    我正在尝试为 django 应用程序构建一个包 但排除所有测试模块 我尝试过设置 exclude tests tests tests tests on find packages并定义一个MANIFEST in 但测试始终会被编译并包含在捆
  • Google SMS Retriever API 无法检索 SMS 消息

    我正在尝试使用 Google 的短信检索器 API 进行自动短信验证 我已按照指示进行操作here https developers google com identity sms retriever overview但我的应用程序没有收到
  • 在WebView中加载本地html?

    我想将本地 html 加载到 WebView 中而不使用 file 因为这不允许 cookie 有没有办法使用 localhost 之类的东西 其次 我找不到在 getSettings 中启用 cookie 的方法 因为使用 file 时不
  • 如何限制只有一台机器才能访问Web应用程序?

    我需要确保访问我的 Web 应用程序的每个用户都只能从一台计算机上执行此操作 因此 100 个用户意味着 100 台计算机 最好的解决方案是什么 在首次登录时检测并存储 IP 是个好主意吗 我认为即使在会话的生命周期内 IP 也可能会发生变
  • 如何摆脱“允许<网站>运行'silverlight'?”在 webdriver 中使用 firefoxprofile 对 Firefox 发出警报

    当使用机器人 api 拖放时 我的鼠标位置受到询问 允许运行 silverlight 的警报的干扰 在全屏模式下运行 firefox 甚至我的 webdriver api 也会受到此警报的影响 因为原本在一个按钮上发生的点击却在另一个按钮上
  • UIViewController -viewDidLoad 没有被调用

    作为 Cocoa 的新手 我遇到了一些问题Interface Builder UIViewController和朋友 我有一个UIViewController子类具有UIView在 xib 中定义 并将控制器的视图出口连接到视图 xib 的
  • WooCommerce 添加到购物车验证:阻止添加到购物车

    我遇到了 woocommerce 的问题 我花了几天时间试图解决 我正在为一个人创建一个网站 他希望我在产品页面上添加自定义输入 我自己无法做到这一点 所以我在网上使用了自由职业者 在产品页面上 我有一个添加到购物车按钮 数量输入和日期输入
  • 在 VBA 中搜索单元格引用的公式

    在 VBA 中 我想搜索 Excel 公式 字符串 以查找单元格引用 具体来说 我想找到字符串中存在相对单元格引用 任何相对单元格引用 而不是特定单元格引用 或混合单元格引用的位置 我不需要找到绝对的单元格引用 尽管我可以检查并忽略它们 我
  • 在 Windows 10 中使用 PS 将程序固定到任务栏

    我正在尝试使用以下代码将程序固定到 Windows 10 RTM 中的任务栏 shell new object com Shell Application folder shell Namespace Join Path env Syste
  • 更新浏览器地址栏而不重新加载

    我喜欢 facebook 在图像之间滚动时更改浏览器地址栏 URL 的方式 以及它在 IE7 上的工作方式 但是 我只找到了有关如何在 HTML5 浏览器上执行此操作的信息 并且我想支持 IE7 由于这是一个 HTML5 解决方案 因此如下
  • 如何为Notepad++编写宏?

    我想为 Notepad 编写一个宏 它应该分别用 char4 char5 char6 替换 char1 char2 char3 Notepad 中的宏只是一堆编码操作 您开始录制 对缓冲区进行操作 也许激活菜单 停止录制然后播放宏 经过调查
  • java中如何将日期时间转换为时间戳

    论坛会员 我在 java 中遇到一个日期时间问题 实际上我正在收到开始日期格式为 2012 02 27T01 10 10我想将收到的日期插入到具有日期时间数据类型的数据库中 实际上我尝试通过下面的代码将收到的开始日期转换为日期时间 Stri
  • Android Eclipse Lint API 检查

    谢谢 P T 看起来像是问题的正确答案在 Eclipse 中构建多 SDK Android 应用程序而不会丢失编译时检查 https stackoverflow com questions 7642249 但是 当我尝试按照建议使用 Tar
  • 读取 spacy 中的文本文件语料库

    我看到的使用 spacy 的所有示例都只是在单个文本文件 尺寸很小 中读取 如何将文本文件语料库加载到 spacy 中 我可以通过腌制语料库中的所有文本来使用 textacy 来做到这一点 docs textacy io spacy rea
  • Azure Blob、文件和磁盘存储

    快问 我已经阅读了大量有关 azure blob 文件 磁盘存储选项的信息 并且我有一个如此简单的存储要求 以至于我对最佳选择感到困惑 我正在阅读的大部分信息都完全超出了我的理解范围 我希望有人能够将视野缩小到更合理的优点 缺点 我的情况如
  • 快速排序与堆排序

    快速排序和堆排序都进行就地排序 哪个更好 首选哪种应用和案例 堆排序是 O N log N 保证的 这比快速排序中最坏的情况要好得多 堆排序不需要更多内存来让另一个数组像合并排序那样放置有序数据 那么为什么商业应用程序坚持使用快速排序呢 与