(1)首先,从一个数组中找出一个最大或最小值,只需要遍历一次,进行n-1次比较就可以得到
for(int i=0;i<array.length;i++){
if(min>array[i]){
min=array[i];
}
(2)同时取出最大最小值呢,同时意味着只经过一次遍历
实际上,至多只需要3*n/2次就可以了
可以将元素按对来处理,先比较每一对的大小,再把大的和最大值比较,小的和最小值比较。
分奇偶:
奇数个:把最大和最小值都先设为第一个值
偶数个:把最大和最小分别设为前两个数。
实际上就是要保证剩下来比较的是偶数个
public void getMax_Min(int a[]){
int len=a.length;
int max=0,min=0;
int i=0,j=len-1;
if(len%2==0){
if(a[0]>a[1])
{ max=a[0];
min=a[1];
}
else{
max=a[1];
min=a[0];
}
i=2;//索引从2开始
}
else{
max=a[0];
min=a[0];
i=1;
}
while(i<j){
if(a[i]<a[j]){
max=a[j]>max?a[j]:max;
min=a[i]<min?a[i]:min;
}
else{
max=a[i]>max?a[i]:max;
min=a[j]<min?a[j]:min;
}
i++;
j--;
}
System.out.println(max+" "+min);
}
在线性时间内求出数组a中的第i小(或大)的元素,以小为例:
public int getRandom_select(int a[],int start,int end,int i){
if(start==end){
return a[start];
}
int q=Partition(a,start,end);
//System.out.println("q"+q+"start"+start+"i"+i);
if((q-start+1)==i){//这里必须要进行q-start+1,不能直接是q,因为i,是变化的,但q是一直是0——a.length最初的索引来算的,所以当是k<i这种情况时候直接用q就是偏大的,看下面粗体
//System.out.println("q"+q+" "+i);
return a[q];
}
int k=q-start+1;//表示的是从start到q总共多少元素
if(k>i)
return getRandom_select(a,start,q-1,i);
else {
return getRandom_select(a,q+1,end,i-k);
}
}
int Partition(int a[],int left,int right)//快速排序的划分,得到枢轴量的下标
{
int i=left;
int j=right;
int temp=a[left];
System.out.println("temp"+temp);
while(i<j)
{
while(i<j && a[j]>=temp)
j--;
if(i<j)
a[i++]=a[j];
while(i<j && a[i]<=temp)
i++;
if(i<j)
a[j--]=a[i];
}
a[i]=temp;
return i;
}
平均情况下:时间复杂度为o(n),最差就是每一次余下的元素都是按最大的划分出来的,则是o(n^2)
*取第5小
0 8 5 2 4 6 3 19 23 20
第一次划分
Start=0,end =9;
得到q=0;,划分后数组
8 5 2 4 6 3 19 23 20
划分的结果是从a[1]=8开始,这时候应该是取第4小,所以在比较时候就必须q-(现在的)start+1***