arrays - 快速选择的运行时间如何得出,CN = 2 N + 2 k ln (N / k) + 2 (N – k) ln (N / (N – k))?
问题描述
从未排序的数组中选择第 k 个最大元素时,运行时间为 CN = 2 N + 2 k ln (N / k) + 2 (N – k) ln (N / (N – k)) (介词取自 Robert Sedgewick 教授的 ALgorithms1)。该实现是一个随机的快速选择。
public static Comparable select(Comparable[] a, int k)
{
StdRandom.shuffle(a);
int lo = 0, hi = a.length - 1;
while (hi > lo)
{
int j = partition(a, lo, hi);
if (j < k) lo = j + 1;
else if (j > k) hi = j - 1;
else return a[k];
}
return a[k];
}
分区子例程是快速排序分区实现,其中 lo 元素用作分区的枢轴。如下图
private static int partition(Comparable[] a, int lo, int hi)
{
int i = lo, j = hi+1;
while (true)
{
while (less(a[++i], a[lo]))
if (i == hi) break;
while (less(a[lo], a[--j]))
if (j == lo) break;
if (i >= j) break;
exch(a, i, j);
}
exch(a, lo, j);
return j;
}
我看到分区的运行时间是(N+1),并且推测分布被打乱,每次运行都会将数组减少到一半,重复出现是(N+N/2+N/4..)所以可以假设 O(N) 时间。这是一个非常乐观的情况。
分布更有可能被分成两半,例如 (C0,Cn-1) 或 (c1, cn-2).. 每个概率为 1/n 倍。现在可以根据上述拆分左侧或右侧中的任何一个的 k 来选择。(如果出现第一种情况,则为 c0 或 cn-1,概率为 1/2N)。现在 cn 将被更改为新的长度,并且将重复相同的步骤直到 j==k。
有人可以帮助推导递归关系及其运行的极限,并最终得出上述 Cn 方程。
注意:-我在 SO 上看到其他人的答案,但他们认为分裂成两半的美好前景,这不太可能发生。像这样一个Quickselect 的平均运行时间
解决方案
推荐阅读
- python - 为什么我们不将参数传递给 read() 函数?
- python - 有什么方法可以检查 Python Socket 中是否有传入消息
- python - PyCrypto 签名验证与其他语言一起失败
- java - 当我有特定的坐标来检测球和砖块之间的碰撞时,为什么球对象会与不可见的墙壁发生碰撞?
- apache-kafka - zookeeper.session.timeout.ms 是否适用于消费者或代理?
- python - 根据某些条件在python中将连续列转换为二进制
- r - 如何将操作按钮引用到闪亮的插入图(insertUI/removeUI)
- ocaml - Psum 不累积(多态高阶函数)而不强制类型
- php - 如何在 woocommerce wordpress php 中为每个使用相同产品的用户设置不同的价格或折扣?
- reactjs - 如何在创建反应应用程序中排除名为 test.js 的源被检测为测试文件?