【问题标题】:sorting algorithm with pagination分页排序算法
【发布时间】:2026-01-10 02:05:01
【问题描述】:

我想对条目列表进行排序,然后选择该排序列表的子集(页面)。例如;我有 10.000 件物品,想要从 101 件到 200 件。 一种天真的方法是首先对所有 10.000 个项目进行排序,然后选择页面;这意味着项目 1 - 100 和 201 - 10.000 都不必要地完全排序。 是否存在一种现有算法,它只会对页面中的项目进行完全排序,一旦明确条目不在页面中,就会停止进一步排序? C中的源代码会很棒,但描述也可以

【问题讨论】:

  • 说没有必要的排序是没有意义的,因为在所有项目都按排序顺序之前,您无法知道某个项目是否会出现在页面上。
  • 第 9999 和 9998 项交换没有关系,只要它们在第 200 项之后即可
  • 你将如何确定前 200 个条目?
  • 我可以想象类似快速排序的方法将是一种选择。如果在第一次迭代之后,列表被分成 2 个未排序的列表,比如 4000 个较低的项目和 6000 个较高的项目,那么 6000 个较高的项目不必进一步排序。
  • @coen:这完全正确,如果你这样做,你最终会得到一个非常好的 O(n) 快速选择算法。如果您不希望大多数页面被请求,这很酷,但是如果请求很多页面,它就会崩溃,因为总成本变得比缓存的初始排序要大得多。

标签: c algorithm sorting pagination


【解决方案1】:

假设你想要从 n 个项目中选出 p 到 q 个项目。虽然排序将花费 O(n·log n) 时间,但您提到的操作可以在 O(n) 时间内完成(只要 q-p « n),如下所示:应用O(n)-time method 来查找 pᵗʰ 和 qᵗʰ 值。然后仅选择具有从 p 到 q 的值的项目,如果 k=q-p,则在时间 O(n+k) 或大约 O(n) 时间,并在时间 O(k·log k) 中对这些项目进行排序,大约是 O (1),如果 k 为 O(1),则净时间 O(n)。

【讨论】:

    【解决方案2】:

    假设您想要的页面以 nth “最小”元素(或最大或您喜欢的任何序数比例)开始。那么你需要将你的部分排序算法分为两步:

    1. 找到第n个元素
    2. 对元素进行排序 {n, n+1, ..., n+s}(其中 s 是页面大小)

    Quicksort 是一种排序算法,可以方便地修改以满足您的需求。基本上,它的工作原理如下:

    • 给定:L 个按顺序相关的元素列表。
    • 如果 L 只包含一个元素,则返回 L
    • L 中随机选择一个枢轴元素 p
    • L分成两组:AB,使得A包含L 小于 pB 包含所有来自 L 的更大的元素。
    • 将算法递归地应用于AB以获得排序的子列表A'B'
    • 返回列表A || p || B,其中 ||表示附加列表或元素。

    您在第 1 步中要做的是运行快速排序,直到找到 nth 元素。所以第 1 步将如下所示:

    • 给定:一个列表 L 的顺序相关元素、一个页面偏移量 n 和一个页面大小 s
    • L 中随机选择一个枢轴元素 p
    • L分为AB
    • 如果A的大小,#A = n-1,则返回p || B.
    • 如果 #A n-1,则递归地应用算法 L' = Bn' = n - #A
    • 如果 #A > n-1,则对 L' = An' = n 递归应用该算法

    此算法返回一个未排序的元素列表,该列表以 nth 元素开始。接下来,在此列表上运行快速排序,但继续忽略 B,除非 #A 。最后,您应该有一个 s 排序元素列表,这些元素大于原始列表中的 n 个元素,但不大于 n+1 原始列表中的元素。

    您要研究的术语是partial sorting。很可能会用 C 或任何足够流行的语言实现它。

    【讨论】: