【最值查找】请设计一个分治算法,从一个长度为n的整数序列中搜索最大元素和最小元素,并分析其计算时间复杂度。
算法分析:每次都取后两个值a,b进行对比,(假设对比结果为a>b)然后将a与已记录的最大值MAX对比,如果a>MAX则将a赋值给MAX,同理处理b与已记录最小值MIN。
解释:
1.划分方法使用每次取两个值得方法而不使用从中间划分的原因:
首先我们知道奇数的情况下,会独立出一个元素,此元素将作为该回合里既是最大值又是最小值,因此一个数与已记录的最大值MAX对比还要与已记录的最小值MIN对比
假如使用每次都从中间划分的方法,产生当个数的情况可分为两大类,一是奇数,二是类似于6,10,14这类平分后成为两个偶数的情况,这类情况产生的奇数个数成对,两个奇数每个花费的比较次数为2,并且像50这类更大的偶数,还可出现更多对的奇数个数对,但是如果合在一起,先两个数区分出大小,再使用大的元素与MAX对比,小的元素与MIN对比,平均下来的花费则可减少为每个1.5
从数组后面开始取的原因是,可以直接在原数组上进行对比即可,控制指针指向的位置,可避免创建新的数组的问题,避免时间与空间的开销
伪代码:
说明:functionA为自定义的函数名,int[] arr是输入带查找的未排序的整形数组,int l 是数组的长度指针,int[]maxmin是记录数组最大值元素与最小值元素,为functionA的输入形参 ; min是自定义函数名,int[]maxmin 是进行对比的数组,a是对比的元素值,默认对比的是maxmin[1];max是自定义函数名,int[]maxmin 是进行对比的数组,a是对比的元素值,默认对比的是maxmin[0];
算法functionA(int [] arr,int l, int [] maxmin)
输入:int[]arr,未排序的整型数组,l为数组的长度,int[]maxmin初始值是无穷小与无穷大
输出:maxmin[0]和maxmin[1],即数组最大值与最小值
S1: function A(int [] arr,int l, int [] maxmin)// l是数组长度,maxmin[0]是最大元素,maxmin[1]是最小元素
S2: if(l==0)
S3: return maxmin;
S4: if(l==1)
S5: max( maxmin,arr[l-1])
S6: min( maxmin,arr[l-1])
S7: return maxmin;
S8: else
S9: if(arr[l-1]>arr[l-2])
S10: max( maxmin,arr[l-1]);
S11: min( maxmin,arr[l-2]);
S12: else(arr[l-1]
S13: max( maxmin,arr[l-2]);
S14: min( maxmin,arr[l-1]);
S15: l = l-2;
S16: return function( arr,l,maxmin);
S17:
S18: int[] min (int [] maxmin, int a)
S19: if(maxmin[1]>a)
S20: maxmin[1] = a;
S21: return maxmin
S22:
S23: int[] max( int [] maxmin ,int a)
S24: if(maxmin[0]
S25: maxmin[0] = a;
S26: return maxmin;
import java.util.Random;
public class BestFInd {
public static int [] functionA(int[] arr, int l, int[] maxmin){
if(l==0){
return maxmin;
}
//查找的数组长度只有1
if(l==1){
max(maxmin,arr[l-1]);
min(maxmin, arr[l-1]);
return maxmin;
}
//数组长度大于等于2的情况
else{
//最后的元素大于倒数第二个元素
if(arr[l-1]>arr[l-2]){
//最后的元素与已记录的最大元素对比大小
max(maxmin,arr[l-1]);
//倒数第二个的元素与已记录的最小元素对比大小
min(maxmin, arr[l-2]);
}
//倒数第二个元素大于最后的元素
else {
//倒数第二个的元素与已记录的最大元素对比大小
max(maxmin,arr[l-2]);
//最后的元素与已记录的最小元素对比大小
min(maxmin, arr[l-1]);
}
//将数组末尾的指针向前移动两位
l = l-2;
//将改变过后的指针、最大最小值数组输入方法继续递归
return functionA(arr,l,maxmin);
}
}
//比较最小值的方法
static int[] min(int[] maxmin, int a){
//默认maxmin[1]储存在最小的元素值,
// 如果a比maxmin[1]小的话,将a赋值给maxmin[1],
// 否则返回原来的数组maxmin
if(maxmin[1]>a)
maxmin[1]=a;
return maxmin;
}
//比较最大值的方法
static int[] max(int[] maxmin, int a){
//默认maxmin[0]储存在最大的元素值,
// 如果a比maxmin[0]大的话,将a赋值给maxmin[0],
// 否则返回原来的数组maxmin
if(maxmin[0]<a)
maxmin[0]=a;
return maxmin;
}
public static void main(String[] args) {
//使用Random进行一个自动生成数组
Random random = new Random();
int number;
int [] arr = new int[101];
lable1:for (int i = 0; i < 101; i++) {
number = random.nextInt(1000);
for(int j = 0;j<=i;j++){
if(arr[j]==number){
i = i-1;
continue lable1;
}
}
arr[i] = number;
}
int [] maxmin = new int [2];
//最大值
maxmin[0] = Integer.MIN_VALUE;
//最小值
maxmin[1] =Integer.MAX_VALUE ;
for (int i :arr ) {
System.out.print(i+" ");
}
System.out.println();
for (int i :BestFInd.functionA(arr,101,maxmin) ) {
System.out.println(i);
}
}
}