技术算法线性时间选择
Kitholt Frank线性时间选择
问题描述:在一个的数组中(数组中的元素有n个),查找第k小的数。
常规思路:若数组有序,直接输出arr[k-1]即可…
但是…
如果一个数组是无序的话,上面的方法就不太行了,因此需要引入线性时间选择。线性时间选择可以模仿快速排序,基本思想是对输入数组进行递归划分,与快速排序不同的是,它只对划分出来的子数组之一进行递归处理
参数说明:
- p:数组最左
- r:数组最右
- k:要查找的第k小的元素
解题步骤:
- 先将数组按五个一组的划分,共有n/5列
- 然后利用任意排序方法求出每一列的中位数
- 将每一列的中位数按照顺序与原数组的前几位元素互换位置
- 再递归求解出中位数的中位数,也就是基准量x
- 用得到的基准在整个数组使用快速排序,得到x在数组中的下标i(第j=i+1-p小的数)
- 将k和j进行比较,若k≤j,说明要查找的数在j的左边的数组,返回步骤一,继续递归
- 反之,则向j的右边的数组递归
不要说了不要说了,先上代码先上代码!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Select { public static Comparable select(int p,int r,int k,int[] arr){ if(r-p<75){ int[] arr1=BubbleSort.bubble(arr); return arr1[p+k-1]; } for(int i=0;i<=(r-p-4)/5;i++){ int s=p+5*i; int t=s+4; for(int j=0;j<3;j++){ Bubble.bubble(arr,s,t-j); Swap.swap(arr,s+2,p+i); } } Comparable x=select(p,(r-p-4)/5,(r-p+6)/10,arr); int i=Partition.partion(p,r, (Integer) x,arr); int j=i-p+1; if (k<=j) return select(p,i,k,arr); else return select(i+1,r,k-j,arr); } }
|