java查找算法(五)--BFPRT查找算法
来源:互联网 发布:颅内压监测数据 编辑:程序博客网 时间:2024/04/27 22:56
在BFPRT算法中,仅仅是改变了快速排序Partion中的pivot值的选取,在快速排序中,我们始终选择第一个元素或者最后一个元素作为pivot,而在BFPTR算法中,每次选择五分中位数的中位数作为pivot,这样做的目的就是使得划分比较合理,从而避免了最坏情况的发生。算法步骤如下:
(1)将输入数组的个元素划分为不大于[n/5]组,每组5个元素,且至多只有一个组由剩下的个元素组成。
(2)寻找>=[n/5]个组中每一个组的中位数,首先对每组的元素进行插入排序,然后从排序过的序列中选出中位数。
(3)对于(2)中找出的>=[n/5]个中位数,递归进行步骤(1)和(2),直到只剩下一个数即为这>=[n/5]个元素的中位数,找到中位数后并找到对应的下标。
(4)进行Partion划分过程,Partion划分中的pivot元素下标为p。
(5)进行高低区判断即可。
本算法的最坏时间复杂度为,值得注意的是通过BFPTR算法将数组按第K小(大)的元素划分为两部分,而
这高低两部分不一定是有序的,通常我们也不需要求出顺序,而只需要求出前K大的或者前K小的。
另外注意一点,求第K大就是求第n-K+1小,这两者等价。TOP K问题在工程中有重要应用,所以很有必要掌握。
/* 思想与随机排序一样,随机排序中吧第一个数当做 pivot ,BFPRT 排序中用中位数的中位数作为 pivot ,使划分效果更好 * 找到中位数的位置后,与 a[low] 交换,这样就转化为随机排序 * 比较a[low]=pivot 值得位置与 k 的大小,确定继续在左右还是右边递归查找 * 最坏情况下时间复杂度为 O(n)( 1)将输入数组的个元素划分为 n/5 组,每组5 个元素,且至多只有一个组由剩下 n%5 的个元素组成。( 2)寻找各个组中每一个组的中位数,首先对每组的元素进行插入排序,然后从排序过的序列中选出中位数。( 3)对于( 2 )中找出的个中位数,递归进行步骤( 1 )和(2 ),直到只剩下一个数即为这个元素 的中位数,找到中位数后并找到对应的下标。( 4)进行 Partion 划分过程, Partion划分中的 pivot 元素下标为。( 5)进行高低区判断即可。 */public class BfprtSearch { public static void main(String args []){ int [] array ={4,45,32,67,5,78,4556,781,1,3,43,765,9,22}; int k ; for (k =1; k<= array.length; k ++){ int k_Num= quickSearch( array,0, array .length-1, k); System. out .println(" 第 "+ k +" 小的元素是: " +k_Num ); } } public static int quickSearch( int []array , int left, int right, int k){ //left,right为下标, k 为第k 小的元素 if( left== right){ return array [left ]; } int mid =getArrayMid (array , left, right); //mid 为中位数 id int mid_new =partition (array , left, right, mid );// 根据中位数划分数组,是中位数在最终的位置上 // 比较中位数与要查找数值的大小 if( mid_new== k-1){ return array [mid_new ]; } else if (mid_new <k -1){ left= mid_new+1; return quickSearch( array, left, right, k); } else { right= mid_new-1; return quickSearch( array, left, right, k); } } public static int getArrayMid( int a [], int l, int r){ //l,r均为数组下标 , 返回中位数的位置 if( l== r){ return l ; } int i =l ; for (;i <=r -l -5;i +=5){// 子数组的元素个数为 5 个时 insertSort( a, i, i+4); //对当前的五个数数进行排序 swap( a, l+( i- l)/5, i+2); //将所有中位数放在数组 array 的前几位上 } if( i< r- l){ insertSort( a, i, r- l); swap( a, l+( i- l)/5,( i+ r- l)/2); //将最后一组数的中位数放在数组 array 的前几位上 } return getArrayMid( a, l, l+( i- l)/5); // 返回中位数的中位数的 id }; public static int partition( int a [], int l, int r, int mid){ int pivot =a [l ]; while (l <r ){ while (l <r && pivot<= a[ r]) r--; a[ l]= a[ r]; while (l <r && pivot> a[ l]) l++; a[ r]= a[ l]; } a[ l]= pivot; return l ; }; public static void swap(int []a , int i , int j ){ int temp= a[ i]; a[ i]= a[ j]; a[ j]= temp; } public static void insertSort( int a [], int l , int r ){ // 对下标为 l到 r之间的元素进行排序 if( l< r){ for( int i= l; i< r; i++){ int j= i+1; int temp= a[ j]; while( j> l&& temp< a[ j-1]){ a[ j]= a[ j-1]; j--; } a[ j]= temp; } } } public static void printArray( int arr []){ for( int k=0; k< arr.length; k++){ System. out.print( arr[ k]+ "\t"); } System. out.print( "\n"); }}
0 0
- java查找算法(五)--BFPRT查找算法
- 五.BFPRT线性查找算法
- BFPRT(线性查找)算法
- 基础算法(四)---线性查找算法(BFPRT)
- 三、线性查找算法,BFPRT 算法 《转》
- BFPRT算法查找第k大元素
- Java查找算法(五): 散列表查找
- BFPRT 算法java实现
- 查找算法(Java)
- 五种查找算法
- 九、线性查找(BFPRT)
- java查找算法(一)--顺序查找
- Java查找算法--线性查找
- BFPRT算法
- BFPRT算法
- BFPRT算法
- BFPRT 算法
- bfprt算法
- java查找算法(四)--随机查找(Randomized-Select)
- onunload、onbeforeunload事件详解
- STM32系列第2篇--GPIO
- Android中如何检测重力感应变化:Sensor和SensorManager
- 物理standby database的日常维护
- java查找算法(五)--BFPRT查找算法
- Android开发问题记录-webview goBack键失效
- tomcat学习手册(一)之Servlet容器(Catalina)
- Android 延时执行操作方法
- (转)Django新手需要注意的10个要点
- 关于hashMap的源码学习
- FusionInsight,让数据“慧”说话
- Tiny4412标准版,编译u-boot并烧录到SD卡,从SD卡启动后只打印‘OK’两个字符
- 使用VTS分析bacnet协议的ReadProperty(一)