Algorithm 证明三向快速排序大O界
对于三向快速排序(双枢轴快速排序),我将如何查找大O边界?有人能告诉我如何推导它吗?好吧,同样的证明也成立 每次迭代将数组拆分为3个子列表,每个子列表的平均大小为Algorithm 证明三向快速排序大O界,algorithm,runtime,big-o,quicksort,Algorithm,Runtime,Big O,Quicksort,对于三向快速排序(双枢轴快速排序),我将如何查找大O边界?有人能告诉我如何推导它吗?好吧,同样的证明也成立 每次迭代将数组拆分为3个子列表,每个子列表的平均大小为n/3。 因此-需要的迭代次数是log_3(n),因为您需要找到执行((n/3)/3)/3)的次数。,直到达到一次。这将为您提供以下公式: n/(3^i) = 1 对于i=log_3(n),这是令人满意的 每次迭代仍然会检查所有的输入(但在不同的子列表中)——与快速排序相同,快速排序为您提供O(n*log_3(n)) 由于log_3(
n/3
。
因此-需要的迭代次数是
log_3(n)
,因为您需要找到执行((n/3)/3)/3)的次数。
,直到达到一次。这将为您提供以下公式:
n/(3^i) = 1
对于i=log_3(n)
,这是令人满意的
每次迭代仍然会检查所有的输入(但在不同的子列表中)——与快速排序相同,快速排序为您提供O(n*log_3(n))
由于log_3(n)=log(n)/log(3)=log(n)*常量
,因此运行时间平均为O(nlogn)
注意,即使您采用更悲观的方法来计算子列表的大小,通过采用均匀分布的最小值-它仍然会得到大小为1/4的第一个子列表、大小为1/2的第二个子列表和大小为1/4的最后一个子列表(均匀分布的最小值和最大值),这将再次衰减到log_k(n)
迭代(使用不同的k>2)-这将再次产生O(nlogn)
总体
正式地,证明如下:
对于每个
n>n\u 1
,对于某些常数c\u 1,n\u 1,每次迭代最多需要运行c\u 1*n
运算。(大O符号的定义,以及每个迭代是O(n)
不包括递归的说法。说服自己为什么这是真的。注意这里的“迭代”指算法在某一“级别”(而非单个递归调用)中完成的所有迭代
如上所述,您在平均情况下有log_3(n)=log(n)/log(3)
现在,我们得到该算法的运行时间T(n)
:
for each n > N_1:
T(n) <= c_1 * n * log(n)/log(3)
T(n) <= c_1 * nlogn
对于每个n>n\u 1:
T(n)事实上,同样的证明成立
每次迭代将数组拆分为3个子列表,每个子列表的平均大小为n/3
。
因此-需要的迭代次数是log_3(n)
,因为您需要找到执行((n/3)/3)/3)的次数。
,直到达到一次。这给出了公式:
n/(3^i) = 1
对于i=log_3(n)
,这是令人满意的
每次迭代仍然会检查所有的输入(但在不同的子列表中)——与快速排序相同,快速排序为您提供O(n*log_3(n))
由于log_3(n)=log(n)/log(3)=log(n)*常量
,因此运行时间平均为O(nlogn)
注意,即使您采用更悲观的方法来计算子列表的大小,通过采用均匀分布的最小值-它仍然会得到大小为1/4的第一个子列表、大小为1/2的第二个子列表和大小为1/4的最后一个子列表(均匀分布的最小值和最大值),这将再次衰减到log_k(n)
迭代(使用不同的k>2)-这将再次产生O(nlogn)
总体
正式地,证明如下:
对于每个n>n\u 1
,对于某些常数c\u 1,n\u 1,每次迭代最多需要运行c\u 1*n
运算。(大O符号的定义,以及每个迭代是O(n)
不包括递归的说法。说服自己为什么这是真的。注意这里的“迭代”指算法在某一“级别”(而非单个递归调用)中完成的所有迭代
如上所述,您在平均情况下有log_3(n)=log(n)/log(3)
现在,我们得到该算法的运行时间T(n)
:
for each n > N_1:
T(n) <= c_1 * n * log(n)/log(3)
T(n) <= c_1 * nlogn
对于每个n>n\u 1:
T(n)发现算法的复杂性与证明算法的复杂性之间有细微的区别
要想找到这个算法的复杂性,你可以按照amit在另一个答案中所说的做:你知道,平均来说,你把你的大小n
问题分成三个较小的大小n/3
问题,这样你就会得到,inèlogèu 3(n)`根据经验,你将开始感受到这种方法,并且能够通过考虑所涉及的子问题来推断算法的复杂性
证明此算法在O(nlogn)中运行
在一般情况下,您使用。要使用它,您必须编写递归公式,给出对数组进行排序所花费的时间。正如我们所说,对大小n
的数组进行排序可以分解为对大小n/3
的三个数组进行排序,再加上构建它们所花费的时间。可以这样编写:
T(n) = 3T(n/3) + f(n)
其中,T(n)
是一个函数,该函数给出了大小为n
的输入的分辨率“时间”(实际上是所需的基本操作数),而f(n)
给出了将问题分解为子问题所需的“时间”
对于三向快速排序,f(n)=c*n
,因为你通过数组,检查每个项目的放置位置,并最终进行交换。这将我们置于其中,表示如果f(n)=O(n^(log_b(a))log^k(n))
对于某些k>=0
(在我们的例子中k=0
),那么
当a=3
和b=3
(我们从递归关系中得到它们,T(n)=aT(n/b)
),这简化为
T(n) = O(n log n)
这是一个证明在发现算法的复杂性和证明算法的复杂性之间有着微妙的区别
要想找到这个算法的复杂性,你可以按照amit在另一个答案中说的做:你知道,平均来说,你需要