Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 将列表分层到无序分区中_Algorithm_Sorting - Fatal编程技术网

Algorithm 将列表分层到无序分区中

Algorithm 将列表分层到无序分区中,algorithm,sorting,Algorithm,Sorting,我正在努力为以下问题找到一个好的算法: 输入:n个整数的未排序列表 输出:p个大小(大致)相等的未排序列表,其中每个列表的最小元素都大于其前面列表的最大元素 目标是对输出进行分层,这样,例如,在p=3的情况下,我可以得到3个无序的小、中、大数字列表(按该顺序) 例如: n=10,p=3 输入:[4,1,8,7,9,3,6,0,2,5] 输出:[[1,0,2],[4,3,6,5],[8,7,9]] 显然,我可以在O(n*log(n))时间内通过简单的排序和分区来完成这项工作,但我想知道这是

我正在努力为以下问题找到一个好的算法:

  • 输入:n个整数的未排序列表
  • 输出:p个大小(大致)相等的未排序列表,其中每个列表的最小元素都大于其前面列表的最大元素
目标是对输出进行分层,这样,例如,在p=3的情况下,我可以得到3个无序的小、中、大数字列表(按该顺序)

例如:

n=10,p=3

  • 输入:[4,1,8,7,9,3,6,0,2,5]
  • 输出:[[1,0,2],[4,3,6,5],[8,7,9]]
显然,我可以在
O(n*log(n))
时间内通过简单的排序和分区来完成这项工作,但我想知道这是否不能在线性时间内完成。我知道QuickSelect在预期的
O(n)
平均情况下运行,所以我的直觉是这个问题应该在
O(p*n)
时间内解决

我天真地认为您可以简单地运行QuickSelect p次,依次找到下一个第k个最小的元素,然后对每个元素执行类似于基数的排序,以按原始步骤中标识的p轴对元素进行分区

因此:

  • 我不确定我概述的算法是否有效
  • 我不确定 确实需要
    O(p*n)
  • 即使是
    O(p*n)
    ,我也不确定 这是一个最佳的复杂性(尽管我怀疑是这样,因为 似乎在p=1和p=n的边缘情况下有效)
  • 不太好 雅致
  • 有更好的算法吗


    谢谢

    我觉得你的算法不错。我唯一的疑惑是,我看不出你怎么能执行你所说的“类似基数的排序”。对于每个值x,您需要确定它进入p个插槽中的哪一个,并且由于这些插槽似乎没有非常特殊的结构(不像在常规的基数排序中,它们对应于某个固定值的倍数),我认为您需要对每个值进行O(log p)比较

    假设只使用比较,则不能比O(n logn)更好,因为如果可以,则只需设置p=n并运行此算法,就可以将n个数字按比O(n logn)更好的顺序排序

    还要注意的是,如果一个值可能出现多次,则生成的子集可能是任意不平衡的。(如果在您的情况下使用严格的“大于”,则这种可能性是不可避免的。)


    最后,如果最坏情况下的性能是一个问题,那么就存在一个问题。它有一个很大的常数,请注意,如果你的输入是异常的模式或者来自潜在的敌意源,那么只考虑它。

    QuestSoad实际上是一个分区算法,所以在快速选择之后不需要额外的步骤。
    让我们假设我们有一个函数分区(arr,lo,hi),它返回一些
    k
    ,这样
    lo给你的例子,
    [[0],[1],[4,8,7,9,3,6,2,5]
    是有效的输出吗?可以在O(p*n)时间内找到
    p-1
    最小的元素,并将每个元素放在一个单件列表中,其余元素放在最终列表中。如果它是无效的,那么你的问题就没有明确说明。很好。目的是使输出列表具有相同的大小+/-1元素。更新问题。
    # After this call:
    #   arr[i] <= arr[med] if lo <= i < med
    #   arr[med] <= arr[i] if med < i < hi
    QuickSelect(arr, lo, med, hi):
      if lo < hi:
        k = Partition(arr, lo, hi)
        if med < k:
          QuickSelect(arr, lo, med, k)
        else if k < med:
          QuickSelect(arr, k + 1, med, hi)
    
    QuickSort(arr, lo, hi):
      if lo < hi:
        k = Partition(arr, lo, hi)
        QuickSort(arr, lo, k)
        QuickSort(arr, k + 1, hi)
    
    Stratify(arr, n, p):
      for i from 0 to p - 2 (inclusive):
        QuickSelect(arr, floor(i * n / p), floor((i+1) * n /p, n) 
    
    Stratum(i, n, p): floor(i * p / n)
    
    QuickStratify(arr, n, p, lo, hi):
      if Stratum(lo, n, p) < Stratum(hi, n, p):
        k = Partition(arr, lo, hi)
        QuickStratify(arr, n, p, lo, k)
        QuickStratify(arr, n, p, k + 1, hi)