1

我读到快速选择的时间复杂度是:

T(n) = T(n/5) + T(7n/10) + O(n)

我将上述内容读作“从 n 个元素中快速选择所需的时间 =(从 7n/10 个元素中选择所需的时间)+(从 n/5 个元素中快速选择所需的时间)+(一些 const *n)”

所以我知道一旦我们找到合适的枢轴,只剩下 7n/10 个元素,并且进行一轮安排枢轴需要时间 n。

但是 n/5 部分让我感到困惑。我知道这与中位数有关,但我不太明白。根据我的理解,中位数的中位数递归地分成 5 并找到中位数,直到你得到 1。

我发现这样做所花费的时间大约是 n 所以 T of mom(n)=n

你如何将 quick_select(n) = T_mom(n)/5 的 T 等同起来?

换句话说,这就是我认为等式应该写的:

T(n)= O(n)+n+T(7n/10)
where,
O(n) -> for finding median
n-> for getting the pivot into its position
T(7n/10) -> Doing the same thing for the other 7n/10 elements. (worst case)

有人可以告诉我哪里出错了吗?

4

2 回答 2

0

在此设置中,T(n) 是指在 n 个元素的数组上计算 MoM 所需的步骤数。让我们一步一步地浏览算法,看看会发生什么。

首先,我们将输入分成大小为 5 的块,对每个块进行排序,形成这些块的中位数的新数组,然后递归调用 MoM 以获得该新数组的中位数。让我们看看每个步骤需要多长时间:

  1. 将输入分成大小为 5 的块:这可以在 O(1) 时间内完成,只需将数组隐式划分为块而不移动任何东西。

  2. 对每个块进行排序:对任何恒定大小的数组进行排序需要时间 O(1)。有 O(n) 个这样的块(具体来说,⌈n / 5⌉),所以这需要时间 O(n)。

  3. 获取每个块的中位数并从这些中位数形成一个新数组。只需查看中心元素,即可在 O(1) 时间内找到每个块的中间元素。有 O(n) 个块,所以这一步需要时间 O(n)。

  4. 在该新数组上递归调用 MoM。这需要时间 T(⌈n/5⌉),因为我们正在对我们在上一步中形成的那个大小的数组进行递归调用。

所以这意味着获得实际中位数的逻辑需要时间 O(n) + T(⌈n/5⌉)。

那么 T(7n/10) 部分是从哪里来的呢?好吧,算法的下一步是使用我们在步骤(4)中找到的中位数的中位数作为分区元素,将元素拆分为小于该枢轴的元素和大于该枢轴的元素。从那里,我们可以确定我们是否找到了我们正在寻找的元素(如果它在数组中的正确位置)或者我们是否需要在数组的左侧或右侧区域进行递归。选择块中位数的中位数作为分裂点的好处是它保证了在这个步骤中较小和较大元素之间的最坏情况 70/30 分裂,所以如果我们必须递归地继续算法,在最坏的情况下如果我们使用大约 7n/10 个元素这样做。

于 2017-01-19T17:45:50.843 回答
-1

在中位数部分的中位数中,我们执行以下操作:

  1. 取子列表的中位数,每个子列表最多有 5 个元素。对于每个列表,我们需要 O(1) 操作,并且有 n/5 个这样的列表,所以总共需要 O(n) 才能找到每个列表的中位数。
  2. 我们取这些 n/5 中位数的中位数(中位数的中位数)。这需要 T(n/5),因为我们应该检查的只有 n/5 个元素。

所以中位数部分的中位数实际上是 T(n/5) + O(n),顺便说一句,T(7n/10) 部分与你所说的不完全一样。

于 2017-01-19T17:35:03.783 回答