这两种算法中有效的一种算法

Efficient one algorithm of these two algorithms

本文关键字:算法 一种 两种 有效      更新时间:2023-10-16

这两种算法都给出了相同的输出,但第一种算法的时间(>.67)几乎是第二种算法的两倍(.36)。这怎么可能?你能告诉我这两种算法的时间复杂度吗?如果它们是一样的,为什么时间不同?

第一种算法:

for (int i =0 ;i<n;i++){
cin>>p[i];
if(i>0){
if(p[i-1]>p[i]){
cout<<p[i]<<" ";
}
else{
cout<<"-1"<<" ";
}
}
}

第二种算法:

for (int i =0 ;i<n;i++){
cin>>p[i];
}
for (int i =0 ; i<n-1;i++){
if(p[i]>p[i+1]){
cout<<p[i]<<" ";
}
else{
cout<<"-1"<<" ";
} 
}

现代处理器中的时间复杂性几乎是无用的性能统计数据。

在这种情况下,我们有一个从0到n-1的算法——O(n)——第二个算法,从0到n-1两次——常数下降,所以它仍然是O(n)。第一个算法有一个额外的if语句,它将恰好为假一次,一个好的编译器将消除它。我们最终得到了相同数量的输入、相同数量的输出、相同数量(有点)的数组访问和相同数量的if (a>b)

第二个有而第一个没有的是决定论。一个循环决定了第二个循环的一切。所有的输入都在第一个循环中被读入。这意味着CPU可以提前准确地看到将要发生的事情,因为它掌握了所有的数字,因此准确地知道if的每个分支将如何运行,并且可以100%准确地预测,加载缓存,并填充管道,使一切都提前准备好,而不会错过任何节拍。

算法1不能做到这一点,因为直到循环的下一次迭代才知道下一个输入。除非输入模式是可预测的,否则很多时候都会猜测if(p[i-1]>p[i])的错误。

附加阅读:为什么处理排序数组比处理未排序数组更快?