使用分而治之的数组的第二大元素
Posted
技术标签:
【中文标题】使用分而治之的数组的第二大元素【英文标题】:Second greatest element of an array using divide and conquer 【发布时间】:2019-11-05 01:09:31 【问题描述】:我编写了这个函数来查找数组的第二大元素,但我对它的时间复杂度有些怀疑。 if 条件有 θ(1) 还是增加了递归调用的时间复杂度?
从实验角度来看,它不应大于分治策略时间复杂度的最大最大元素。
int secondmax(int arr[], int first , int last)
if(first+1==last) return arr[first];
int mid= first +(last-first)/2;
int left = secondmax(arr, first, mid);
int right = secondmax(arr, mid, last);
if( (left > right ? left : right) > max1)
max2=max1;
max1= left > right ? left : right;
else if((left > right ? left : right) > max2 && (left > right ? left : right) != max1)
max2= left > right ? left : right;
return left > right ? left : right;
ps max1, max2 是全局变量,可能我可以删掉 max1
【问题讨论】:
如果条件。是 theta(1),过客,我收藏了,不错 qn。 您应该始终在此处返回一个 2 元组,因为如果它们都是第二个最大值,那么您可能会在此处选择第三个最大值。 如果您可以将编译器从不必要的计算负载中解救出来,那就更好了。例如,在您的情况下,left > right ? left : right
被使用 >1 次。另外,请注意,无论在何处使用它,它都不会产生不同的东西,因此不需要重复调用。因此,为了避免这种情况,您可以简单地使用一个变量来存储比较的结果,然后随时随地调用该变量。
我不认为这个功能真的有效,虽然我不清楚预期的用途是什么。我的猜测是您的意图是 max2
保存结果,因为 max1
和函数的返回值似乎都是向量的最大值。 (使用全局变量是糟糕的设计,因为这意味着您只能在程序中调用该函数一次,除非您知道每次都重置它们。)
【参考方案1】:
if
在递归调用之前的时间复杂度方面并不是一个重要的贡献者。给定您的算法,最重要的是使用递归完成的数组拆分对时间复杂度的贡献。对您的算法进行试运行可以让您看到您的算法将遵循以下递归方程:T(n) = 2T(n/2) + θ(1)。请注意,此处的 θ(1) 表示您在 2 次递归函数调用之后编写的指令所消耗的恒定时间单位。这个 θ(1) 将与否相同。在递归调用之后,指令的数量是不变的。如果您使用一个运行时间取决于输入数组长度的循环,那么 θ(n) 将代替 θ(1) 出现。
那么,θ(1) 和 θ(n) 如何影响算法的复杂性?可以通过在递归方程上使用旧的 Master's Method 来简单地确定它。
对于 θ(1),您的等式将是:T(n) = 2T(n/2) + θ(1) & 对于 θ(n),它将变为 T(n) = 2T(n/2) + θ(n)。 在对这两种情况应用 Master's Theorem 之后,您将得到最终的时间复杂度,即第一个的 θ(log n) 和第二个的 θ(n [log n])。所以,这是您需要记住的主要区别。
【讨论】:
感谢您对此以及有关编译器计算负载的建议,我不知道。以上是关于使用分而治之的数组的第二大元素的主要内容,如果未能解决你的问题,请参考以下文章
SIGABRT(信号 6)在使用分而治之的数组中查找多数元素时出错