五个数的中位数有时被用作算法设计练习,已知可以使用仅6次比较进行计算。
如何在C#中最好地实现这个"使用6次比较的五个数的中位数"?我所有的尝试似乎都导致笨拙的代码 :( 我需要漂亮易读的代码,同时仍然只使用6次比较。
public double medianOfFive(double a, double b, double c, double d, double e){
//
// return median
//
return c;
}
注意: 我认为我应该在这里提供"算法":
我发现自己无法像Azereal在他的论坛帖子中那样清楚地解释这个算法。因此,我将参考他的帖子。来自http://www.ocf.berkeley.edu/~wwu/cgi-bin/yabb/YaBB.cgi?board=riddles_cs;action=display;num=1061827085
好吧,我在我的任务中遇到了这个问题,我求助于这个论坛,但是没有得到帮助。 最终我找出了如何做。
使用前4个元素开始归并排序,并对每一对进行排序(2次比较)
比较每一对中的两个较小数,并从可能性中排除最低的一个(3次比较)
将第5个数字添加到没有成对的数字中,并进行比较(4次比较)
比较两个新对中的最低值,并排除最低的一个(5次比较)
将孤立的数字和最后一对中的较低数字进行比较,较低的数字是中位数
可能的中位数在括号内
(54321)
5:4 3:2 2次比较
(4<5 2<3 1)
4:2 3次比较
2(4<5 3 1)
1:3 4次比较
2(4<5 1<3)
4:1 5次比较
1,2(4<5 3)
4:3 6次比较
1,2(3)4,5
三是中位数
这是我编写的用于查找五个数的中位数的C++代码。不要介意它的笨拙:
double StageGenerator::MedianOfFive(double n1, double n2, double n3, double n4, double n5){
double *a = &n1, *b = &n2, *c = &n3, *d = &n4, *e = &n5;
double *tmp;
// makes a < b and b < d
if(*b < *a){
tmp = a; a = b; b = tmp;
}
if(*d < *c){
tmp = c; c = d; d = tmp;
}
// eleminate the lowest
if(*c < *a){
tmp = b; b = d; d = tmp;
c = a;
}
// gets e in
a = e;
// makes a < b and b < d
if(*b < *a){
tmp = a; a = b; b = tmp;
}
// eliminate another lowest
// remaing: a,b,d
if(*a < *c){
tmp = b; b = d; d = tmp;
a = c;
}
if(*d < *a)
return *d;
else
return *a;
}
它应该更紧凑,不是吗?
正如@pablito在他的答案中指出的那样,内置的List.Sort()
无法满足此要求,因为它最多使用13次比较 :]