这是一个面试问题。假设你有一个名为A的四个整数数组,还有这个函数:
int check(int x, int y){
if (x<=y) return 1;
return 0;
}
现在,您要创建一个将A排序的函数,并且您只能使用函数check
进行比较。您需要多少次check
来电?
(可以为结果返回一个新数组)。
我发现我可以通过5次通话完成此操作。是否可以用较少的电话(最糟糕的情况下)进行?
这就是我想到的方法(伪代码):
int[4] B=new int[4];
/*
The idea: put minimum values in even cells and maximum values in odd cells using check.
Then swap (if needed) between minimum values and also between maximum values.
And finally, swap the second element (max of minimums)
and the third element (min of maximums) if needed.
*/
if (check(A[0],A[1])==1){ //A[0]<=A[1]
B[0]=A[0];
B[2]=A[1];
}
else{
B[0]=A[1];
B[2]=A[0];
}
if (check(A[2],A[3])==1){ //A[2]<=A[3]
B[1]=A[2];
B[3]=A[3];
}
else{
B[1]=A[3];
B[3]=A[2];
}
if (check(B[0],B[1])==0){ //B[0]>B[1]
swap(B[0],B[1]);
}
if (check(B[2],B[3])==0){ //B[2]>B[3]
swap(B[2],B[3]);
}
if (check(B[1],B[2])==0){ // B[1]>B[2]
swap(B[1],B[2]);
}
答案 0 :(得分:4)
4元素列表有24种可能的排序。 (4阶乘)如果只进行4次比较,那么你只能获得4位信息,这足以区分16种不同的情况,这不足以涵盖所有可能的输出情况。因此,5个比较是最佳的最坏情况。
答案 1 :(得分:2)
计算机编程艺术,p。 183(第3.5.1节),Donald Knuth在最小比较数字上有下表和上限:
ceil(ln n!)
是“信息理论”下限,而B(n)
是插入二进制排序中的最大比较数。由于n=4
的下限和上限相等,因此需要进行5次比较。
信息理论界限是通过识别n!
个唯一项目的n
可能排序而得出的。我们通过以S
的形式询问is X<Y?
是 - 否问题来区分这些情况。这些问题构成了一个最多有2^S
个提示的树。我们需要n!<=2^S
;求解S
会得到ceil(lg(n!))
。
顺便说一下,您可以使用Stirling's approximation来表明这意味着排序需要O(n log n)
时间。
本节的其余部分接着描述了创建这些边界和研究这个问题的一些方法,尽管工作正在进行中(例如,参见Peczarski (2011))。