Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 证明三向快速排序大O界_Algorithm_Runtime_Big O_Quicksort - Fatal编程技术网

Algorithm 证明三向快速排序大O界

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(

对于三向快速排序(双枢轴快速排序),我将如何查找大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)=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在另一个答案中说的做:你知道,平均来说,你需要