公司有一袋金块(共 n 块,n 是 2 的幂,且 n≥2),年终时,最优秀的员 工得到其中最重的一块,最差的员工得最轻的一块。现有一台比较重量的仪器, 希望用最少的比较次数找出最重和最轻的金块,请分别用非递归和递归方式实现。
1.非递归方法
将重量输入数组中,按顺序两两(1和2,3和4等)比较,找出每一对中的大的和小的,分别存入两个占原本长度一半的数组中。
所以一个数组存放的是每一对中的大数,另一个数组存放的是每一对中的小数。
再按同样的方式两两比较,直到最后两个数组中分别只剩一个数,即为最大数和最小数。
#include<iostream>
using namespace std;
float compareAx(float a,float b){ //比较大小,返回大的值
if(a>b) return a;
else return b;
}
float compareIn(float a,float b){ //比较大小,返回小的值
if(a<b) return a;
else return b;
}
int main(){
int n;
float weight;
cout<<"请输入金块的数量";
cin>>n;
cout<<"请依次输入金块的重量:";
float* gold; //用于找出最大的重量
float* goldd; //用于找出最小的重量
gold=new float[n];
goldd=new float[n];
for(int i=0;i<n;i++){
cin>>weight;
gold[i]=weight;
goldd[i]=weight;
} //将重量依次输入到数组内
while(n>=2){
float* gold1;
float* gold2;
n=n/2;
gold1=new float[n];
gold2=new float[n];
for(i=0;i<2*n;i=i+2){
gold1[i/2]=compareAx(gold[i],gold[i+1]);
gold2[i/2]=compareIn(goldd[i],goldd[i+1]);
}
gold=gold1;
goldd=gold2;
}
cout<<"最重的"<<gold[0]<<"克"<<endl;
cout<<"最轻的"<<goldd[0]<<"克"<<endl;
return 0;
}
2.递归方法
a.当有两个数字时,可以很容易比较大小。
b.当有四个数字时,将数字分为两组,每组两个数,分别按a处理,结果再按a处理。
c.当有数字为2的幂个时,将数字分为两组,再两组。。。直到每组两个数,再分别按a处理,结果再分组。。。最后再按a处理。
#include<iostream>
using namespace std;
float* compareMm(float a,float b){ //找出两个数中的大数和小数,存放在长度为2的数组中
float* c=new float[2];
if(a>b){
c[0]=a;
c[1]=b;
}
else{
c[0]=b;
c[1]=a;
}
return c;
}
float *Mm(int n1,int n2,float *g){ //n1为要计算数组中最大值的起始位置,n2为结束位置
if((n2-n1+1)==2){ //需要计算的长度为2时可直接调用函数比较
return compareMm(g[n1],g[n2]);
}
else{
int k=n1+(n2-n1)/2;
float *lm=Mm(n1,k,g); //递归调用,将左侧和右侧分开
float *rm=Mm(k+1,n2,g);
float *result=new float[2];
if(lm[0]>rm[0])
result[0]=lm[0];
else
result[0]=rm[0];
if(lm[1]<rm[1])
result[1]=lm[1];
else
result[1]=rm[1];
return result;
}
}
int main(){
int n;
float weight;
cout<<"请输入金块的数量";
cin>>n;
cout<<"请依次输入金块的重量:";
float *gold;
gold=new float[n];
for(int i=0;i<n;i++){
cin>>weight;
gold[i]=weight;
} //向数组中输入数据
float *re=Mm(0,n-1,gold);
cout<<"最重的"<<re[0]<<"克"<<endl;
cout<<"最轻的"<<re[1]<<"克"<<endl;
return 0;
}