指针和数组混淆的 K&R Qsort 示例

2023-11-24

我发现很难理解下面的代码片段。我理解所显示的指向函数风格的指针,但我发现混乱之处在于指示的行中。

void qsort(void **v, int left, int right, int (*comp) (void *, void *))
{
    int i, last;
    void swap(int **v, int i, int j);

    if (left >= right)   /* do nothing if array contains */
        return;           /* fewer than two elements */
    swap(v, left, (left + right)/2);   /* move partition elem */ [1]
    last = left;                       /* to v[0] */ [2]
    for (i = left + 1; i <= right; i++) /* partition */ [3]
        if ((*comp) (v[i], v[left]) < 0) [4]
            swap(v, ++last, i); [5]
    swap(v, left, last);        /* restore partition elem */ [6]
    qsort(v, left, last - 1); [7]
    qsort(v, last + 1, right);  [8]

}

有人可以向我解释这个例程,特别是指示的行,只需告诉我它在做什么,因为我无法弄清楚这个 qsort,我在阅读 k&r 时阅读的爱斯基摩指南说 qsort 例程是垃圾,而且过于复杂。我只需要理解为什么这样写,因为这对我来说毫无意义。

感谢您阅读本文,即使没有任何意义。


这是一段漂亮的代码!

首先,了解快速排序背后的想法很重要:

1)列出一个数字。

2)选择一个,称之为X。

3) 制作两个列表,其中一个是所有小于 X 的数字,另一个是所有大于 X 的数字。

4)对小于X的数进行排序。对大于X的数进行排序。

这个想法是,如果我们幸运地为 X 选择一个好的值,那么小于 X 的数字列表的大小与大于 X 的数字列表的大小相同。如果我们从 2*N+1 个数字开始,那么我们得到两个包含 N 个数字的列表。每次,我们希望除以二,但我们必须对 N 个数字进行排序。我们可以将 N 除以 2 多少次?这就是 Log(N)。 所以,我们排序 N Log(N) 次。这很棒!

至于代码是如何工作的,这里是运行过程,还有一些草图。我们将选择一个小数组:)

这是我们的数组:[DACBE]

开始时,left=0,指向D。right=4,指向E。

现在,按照代码和标签进行操作:

[1] 交换(v,0,2) [DACBE] -> [CADBE]

我们已经交换了选择的值并将其放在数组的开头。

[2]最后=0

这有点聪明……我们想保留一个计数器,这样我们就知道哪些值更大,哪些值更小……你会看到这是如何进展的

[3] 对于 (i=1;i

对于列表中的所有剩余元素...

[4] if ((*comp)(v[i], 'C')

如果 i 处的值小于“C”...

[5] 交换(v,++last,i);

把它放在列表的开头!

让我们运行 3,4,5 的代码

i=1:

[CADBE]

如果('A'

swap('A','A') (最后递增!)

[CADBE]->[CADBE](无变化)

last=1

i=2:

[CADBE]

如果 ('D'

失败了。继续前行。

i=3:

[CADBE]

如果('B'

swap('B','D') 最后递增!

[CADBE] -> [CABDE](看!正在排序!)

last=2

i=4:

[CABDE]

如果 ('E'

失败了。继续前行。

好吧,艾斯。这样循环给出的是 [CABDE], last=2 ('B')

现在第 [6] 行...swap(left,last)...即 swap('C','B') [CABDE] -> [BACDE]

现在,它的神奇之处在于......它是部分排序的! BA

现在我们对子列表进行排序!

[7] -> [BA] -> [AB]

so

[BACDE] -> [ABCDE]

[8]-> [德语]->[德语]

so

[ABCDE] -> [ABCDE]

我们就完成了!

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

指针和数组混淆的 K&R Qsort 示例 的相关文章

随机推荐

  • 如何将数字转换为单词 - ORACLE

    我编写了一个非常简单的查询 其结果为 500 我需要如下转换该值 old value 500 new value FIVE HUNDERED 使用卢克的力量 SqlFiddle演示 SELECT UPPER TO CHAR TO DATE
  • 作为启动上下文提供时 CoroutineExceptionHandler 不执行

    当我运行这个时 fun f runBlocking val eh CoroutineExceptionHandler e gt trace exception handler e val j1 launch eh trace launche
  • 如何使用 StylePlaceHolder 和 Style 控件控制 ASP.NET 主题中的样式表

    Update 这变成了一篇博客文章 包含更新的链接和代码 位于我的博客上 https egilhansen com 2008 12 01 how to take control of style sheets in asp net them
  • 为什么 cfcookie 不允许将 domain= 设置为 CFID/CFTOKEN 的子域?

  • phpMyAdmin 报告“无权限”

    长话短说 我最终从 EasyPHP 中的 PHPMyAdmin 中删除了 root 用户 经过一番研究 我使用了skip grant tables来重新获得数据库访问权限 然而 现在我不能做任何事情 因为 root 用户有 无特权 也就是说
  • Pyppeteer:浏览器在 AWS Lambda 中意外关闭

    我在 AWS Lambda 中遇到此错误 看来 devtools websocket 没有启动 不知道如何修复它 有任何想法吗 谢谢你的时间 异常源自get ws endpoint 由于websocket响应超时https github c
  • 在 Swift 中迭代字典

    我对 Xcode 在 Swift 编程语言指南 中给我的这个实验的答案有点困惑 Use a for in to iterate through a dictionary experiment let interestingNumbers P
  • 如何使 JXTreeTable 对其顶部元素进行排序

    我知道 我已经查看了来源 JXTreeTable 上的排序已被禁用 但是 我希望允许仅根据根节点的直接子节点的值对所有列进行排序 假设我有这样的结构 Name Date File UID Root Mr X 1996 10 22 AE123
  • rspec 和 Shoulda - 互补还是替代?

    我已经使用shoulda有一段时间了 并且我已经阅读并使用了rspec 我没有做过深入的比较和对比 但在我看来 两者之间有一些重叠 但它们并不是一对一的替代 我正在考虑使用 rspec 在我的 Rails 系统中编写一些单元测试 而不替换用
  • Django ORM:覆盖子类中字段的 related_name

    我得到这个异常 django core exceptions FieldError 类 SpecialPlugin 中的本地字段 ticket 与基类 BasePlugin 中名称相似的字段发生冲突 这是我的模型 class BasePlu
  • 点击屏幕顶部状态栏时 UITableView 滚动到顶部

    我插入了一个UITableView在另一个里面UIViewController的观点 但是当我点击屏幕顶部的状态栏时 表视图不会滚动到顶部 这是 iOS 应用程序中的预期行为 我试过 self tableView setScrollsToT
  • 更改实例变量

    我有这个代码 class Yes def init self self a 1 def yes self if self a 1 print Yes else print No but yes class No Yes def no sel
  • 控制android状态栏图标

    我正在尝试对状态栏中图标的状态进行一些控制 我希望能够执行以下操作 保留图标 在状态栏中可见 只要 当应用程序运行时 即使用户选择清除状态栏 清除状态栏中的图标 如果应用程序退出 即使 特别是 它被杀死 我意识到当应用程序显式退出时我可以将
  • 将 Relay 与 React-Native 结合使用时的条件片段或嵌入式根容器

    我有relay与 一起工作react native 但我对如何最好地利用中继路由和根容器感到困惑 特别是在使用Navigator呈现多条路线 参加以下课程 var Nav React createClass renderScene rout
  • 测试用例和断言语句

    代码在这个问题让我思考 assert value gt 0 Precondition if value gt 0 Doit 我从不写 if 语句 断言就足够了 你全部can做 早早崩溃 经常崩溃 代码完成 states 断言语句使应用程序正
  • 以下位操作的优化机会?

    您认为 haswon 函数还有优化的空间吗 见下文 我认识到将参数类型从 int64 to unsigned int64使该功能比我想象的更快 也许还有优化的机会 更详细地说 我正在写一个连接四个游戏 最近我使用了Profiler很困并认识
  • 如何在 Visual Studio 2008 中自定义复制/粘贴行为?

    如何在 Visual Studio 2008 中自定义复制 粘贴行为 例如我创建一个新的 div div 然后将其复制并粘贴到同一个文件中 VisualStudio 粘贴 div div 而不是我复制的原文 更令人沮丧的是 当我尝试复制一组
  • 通过 Javascript 访问 Google Apps 公共电子表格

    花了很多时间看这个 似乎有关访问 Google apps 电子表格的少量信息维护得不是很好 今年的 Google IO 上宣布了增强的 Google apps 脚本 包括 UI 元素 这让我想到创建一个基于 Google 电子表格中的数据的
  • 在 MVC 操作中将 SSRS 报告导出为 PDF

    是的 我想将 SSRS 报告导出为 PDF 并从我的操作中返回它 我没有任何报告查看器 请建议我如何实现这一目标 到目前为止我已经做到了 public void SqlServerReport NetworkCredential nwc n
  • 指针和数组混淆的 K&R Qsort 示例

    我发现很难理解下面的代码片段 我理解所显示的指向函数风格的指针 但我发现混乱之处在于指示的行中 void qsort void v int left int right int comp void void int i last void