eal*_*eon 4 algorithm time-complexity quickselect
从https://en.wikipedia.org/wiki/Quickselect它说
“然而,不像快速排序那样递归到两边,quickselect 只递归到一侧——它正在搜索的元素所在的一侧。这将平均复杂度从 O(n log n) 降低到 O(n),其中O(n^2) 的最坏情况。”
我不明白减少到只看一侧如何将平均复杂度降低到 O(n)?是不是更多的 O(N/2 log N) 仍然是 O(N log N)。最坏的情况如何 O(n^2)
Aro*_*ger 19
当我读到平均时间复杂度是 O(n) 而我们每次将列表分成两半(如二分搜索或快速排序)时,一开始我也感到非常矛盾。为了证明只看一侧可以将平均运行时复杂度从 O(n log n) 降低到 O(n),让我们比较一下快速排序(2 侧)和快速选择(1 侧)的时间复杂度递归关系。
快速排序:
T(n) = n + 2T(n/2)
= n + 2(n/2 + 2T(n/4))
= n + 2(n/2) + 4T(n/4)
= n + 2(n/2) + 4(n/4) + ... + n(n/n)
= 2^0(n/2^0) + 2^1(n/2^1) + ... + 2^log2(n)(n/2^log2(n))
= n (log2(n) + 1) (since we are adding n to itself log2 + 1 times)
Run Code Online (Sandbox Code Playgroud)
快速选择:
T(n) = n + T(n/2)
= n + n/2 + T(n/4)
= n + n/2 + n/4 + ... n/n
= n(1 + 1/2 + 1/4 + ... + 1/2^log2(n))
= n (1/(1-(1/2))) = 2n (by geometric series)
Run Code Online (Sandbox Code Playgroud)
我希望这能让您相信为什么只看一侧会产生不同!
Jim*_*hel 17
n log(n)意味着该算法查看所有 N 项 log(n) 次。但这不是 Quickselect 发生的情况。
假设您正在使用 Quickselect 选择 128 个列表中的前 8 个项目。通过随机选择的奇迹,您选择的支点始终位于中间点。
在第一次迭代中,该算法查看所有 128 个项目并将其划分为两组,每组 64 个项目。下一次迭代分为两组,每组 32 个项目。然后是 16,然后是 8。 检查的项目数是:
N + N/2 + N/4 + N/8 + N/16
Run Code Online (Sandbox Code Playgroud)
该系列的总和永远不会达到 2*N。
最坏的情况是分区总是导致分区大小非常倾斜。考虑如果第一个分区只删除一个项目会发生什么。第二个只删除了一个,等等。结果是:
N + (N-1) + (N-2) ...
即(n^2 + n)/2), 或 O(n^2)。