线性时间选择算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/**
* 线性时间选择算法
*
* */
public class Xianxing {
public int showNumber(int i)
{
System.out.printf("第%d小的数为:",i);
return i;
}
//交换方法
public void swap(int[] p,int i,int j)
{
int m=p[i];
p[i]=p[j];
p[j]=m;
}
//插入排序完整排序算法
public void insertSort(int[] a,int start,int end)
{
for(int i=start+1;i<=end;i++)
{
int daipai=i;
while(daipai>0 && a[daipai-1]>a[daipai])
{
int m=a[daipai];
a[daipai]=a[daipai-1];
daipai--;
a[daipai]=m;
}
}
}
//冒泡排序完整排序算法
public void sortAll(int[] a,int start,int end)
{
for(int i=start;i<end;end--)
{
for(int j=i+1;j<=end;j++)
{
if(a[j]<a[j-1])
{
this.swap(a,j,j-1);
}
}
}
}
//冒泡排序一趟排序算法(从小到大),每次只排好最后一个数
public void bubbleSortOne(int[] a,int start,int end)
{
for(int i=start;i<end;i++)
{
if(a[i+1]<a[i])
{
this.swap(a, i+1, i);
}
}
}
//快速排序一趟排序算法,每次将指定的数位置排好,返回指定数的下标
public int partitionSortOne(int[] a,int start,int end,int aim) {
//找到aim对应的下标k
int k;
for(k=start;k<=end;k++)
{
if(a[k] == aim)
{
break;
}
}
//
if(start == end)
{
return k;
}
//将基准位置换到开始位置,便于用于快速排序
swap(a,start,k);
k=start;
//快速排序关键步骤,通过变换基准的位置实现
while(start != end)
{
if(k == start)
{
if(a[end]<a[k])
{
swap(a,end,k);
k=end;
start++;
}
else
{
end--;
}
}
else if(k == end)
{
if(a[start]>a[k])
{
swap(a,start,k);
k=start;
end--;
}
else
{
start++;
}
}
}
return k;
}
//选择算法
public int select(int[] a,int start,int end,int num)
{
//数组数的个数小于5,直接排序,并返回第num小的元素
if(end-start<5)
{
this.sortAll(a, start, end);
/*System.out.println(start+num-1+"\t"+a[start+num-1]);*/
return a[start+num-1];
}
//找出每5个数的中位数,并保存为a[start+i],剩下一组少于5个数的不用管
int i; //i表示分成组的个数
for(i=0;i<(end-start+1)/5;i++)
{
int starti=start+5*i;
int endi=starti+4;
for(int j=0;j<3;j++)
{
this.bubbleSortOne(a,starti,endi-j);
}
this.swap(a, start+i, starti+2);
}
//找到中位数的中位数的值x
int x=this.select(a, start, start+i,(i+3)/2);
//用一趟快速排序算法找到x的位置,并把数分为两部分,位于x左边的数都小于x,位于x右边的数都大于x
int j=this.partitionSortOne(a,start,end,x);
//num小于基准(中位数的中位数的下标)相对于开始位置时,在左边找;否则在右边找
if(num<=j-start+1)
return select(a,start,j,num);
else
return select(a,j+1,end,num-j+start-1);//j-start+1表示在此次选择过程中j左边数的个数(包括j)
}
//显示数组
public void showArray(int[] p)
{
for(int i=0;i<p.length;i++)
{
System.out.print(p[i]+" ");
}
System.out.println();
}
//main方法
public static void main(String[] args)
{
Xianxing x=new Xianxing();
int[] arr={3,6,8,4,2,9,5,89,7,6,6,6,6,7,9,8,5,4};
x.showArray(arr);
int m=x.select(arr,0,arr.length-1,x.showNumber(12));
System.out.println(m);
/*x.showArray(arr);
x.sortAll(arr,0,arr.length-1);*/
x.insertSort(arr, 0, arr.length-1);
x.showArray(arr);
}
}。