CLRS告诉我们将A[r]
与A[i]
交换,其中i是p和r之间的随机变量。但是,如果我随机选择一个变量作为quicksort函数中的枢轴并交换值,那么现在的时间复杂度是多少?
算法现在的表现会比本书中的算法差吗?
这是代码
package Clrs;
import java.util.Random;
public class Clrs
{
public static void main(String[] args)
{
int[] a = new int[]{7,6,5,4,3,2,1};
quicksort(a,0,a.length-1);
System.out.println();
for (int i : a) {
System.out.println(i);
}
}
static void quicksort(int a[],int p,int r)
{
int q;
if(p<r)
{
Random random = new Random();
int y = p+random.nextInt(r-p+1);
int temp = a[y];
a[y]=a[r];
a[r]=temp;
q = partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}
static int partition(int a[],int p,int r)
{
int x=a[r];
int i=p-1;
for (int j = p; j <= r-1; j++) {
if(a[j]<=x)
{
i++;
swap(a,i,j);
}
}
swap(a,i+1,r);
return i+1;
}
static void swap(int a[],int x,int y)
{
int t=a[x];
a[x]=a[y];
a[y]=t;
}
}
答案 0 :(得分:3)
理论复杂性保持不变。 O(nlogn)
平均情况和O(n^2)
最坏情况。
选择随机支点的想法不是要消除O(n^2)
的最坏情况表现 - 这仍然可能发生,概率很低。
这个想法是让算法对恶意输入的攻击更加有效。
当伪随机选择枢轴时,预测哪个阵列会导致最坏情况的行为要困难得多,所以如果有人想要攻击我们的程序,并使其工作速度明显变慢 - 那对他来说就会困难得多这样做。
另一个问题是确保如果您的数据倾向于以某种模式出现 - 最坏的情况不会一遍又一遍地重复(很有可能)。
作为旁注,将第一个(或最后一个)元素作为“经典”快速排序的枢轴,这是一个坏主意,因为数组在现实生活应用程序中排序或几乎排序的概率远高于一个会期望,导致算法经常陷入最坏的情况。有关它的更多信息可以在这个帖子中找到: Why are we interested in how long it takes to sort a file that is already sorted?
答案 1 :(得分:0)
当我们谈论某些算法的Big-O复杂性时。我们经常谈论理论平均时间复杂度。虽然您必须意识到最糟糕的情况是时间复杂性可能比平均时间复杂得多。
例如,快速排序O(n log n)平均计算复杂度。但最坏的情况是O(n2),当你的原始阵列完全颠倒并且你选择了不好的支点。