【问题标题】:Why is the time complexity of nested while loops in Quicksort not O(n^2)?为什么 Quicksort 中嵌套 while 循环的时间复杂度不是 O(n^2)?
【发布时间】:2022-01-07 01:31:32
【问题描述】:
def partition(l, h):
    i, j = l, h
    while i < j:
        while arr[l] > arr[i]:
            i += 1
        while arr[j] > arr[l] and j >= 0:
            j += 1
        if i < j:
            arr[i], arr[j] = arr[j], arr[i]
    arr[l], arr[j] = arr[j], arr[l]
    return j

嵌套while循环的时间复杂度为O(n2),以上sn-p代码来自Quicksort。那么整体时间复杂度O(n log n)如何呢?

【问题讨论】:

  • 如果所有级别的循环都执行 n 次,则只需 O(n^2)。但是嵌套循环正在处理数组的较小部分,这使得它 O(n log n)。
  • 您确定这是j += 1 而不是j -= 1
  • 快速排序实际上是 O(n^2)。在 expected 的情况下只有 O(n lg n)。
  • 我很确定代码有问题。第一个内部while 循环条件在开始时永远不会为真,因为i 等于l,因此i 永远不会增加,即使在值开始被发生的交换移动之后在外循环的末尾。如果无法正常工作,我不确定这段代码是否值得分析!
  • 理解嵌套循环的复杂性很重要...取决于循环的细节。考虑:for i in range(10): for j in range(10): print(i*j)恒定时间

标签: python while-loop nested-loops quicksort


【解决方案1】:

分区函数需要线性时间——正如 cmets 指出的那样,您要分区的列表的大小会减小,从而允许O(n log n) 运行时的可能性。

但是,如果您选择的分区点不佳,快速排序将在 O(n^2) 中运行。例如,考虑您的分区选择数组中尚未成为分区的最大元素的情况。那么运行时可以表示为T(n) = T(n - 1) + O(n) ==&gt; O(n^2)

但是,随机选择分区会给出O(n log n) 的预期时间。如果您希望在最坏的情况下使用O(n log n) 运行时,您可以使用确定性中值查找算法(例如these slides 中给出的算法)来找到一个好的分区。 (这些幻灯片还正式证明了随机快速排序的预期运行时间。)

【讨论】:

  • 可能值得指出的是,即使在 O(N^2) 的情况下枢轴不好,问题代码中显示的嵌套循环仍然只需要 O(N) 时间,而是它们再重复 N 次,使得整个算法 O(N^2)。
  • 已编辑为原始答案。感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-14
  • 2020-11-20
  • 2018-12-13
  • 2017-02-27
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多