您的位置:首页 > 其它

从一个数组中同时找出最大最小数-算法导论第九章

2017-10-11 22:22 288 查看
(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***
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法导论
相关文章推荐