BFPRT算法
算法思想:
对于求数组中第k小的元素的问题,我们已经有很好的常规算法了,这个算法在最好的情况下时间复杂度是O(n),但在最坏的情况下是O(n^2)的。
bfprt算法就是在这个基础上改进的。它通过中位数概念选取最合适的划分值作为划分依据。
常规解法:
我们随机在数组中选择一个数作为划分值(number),然后进行快排的partation过程(将小于number的数放到数组左边,等于number的数放到数组中间,大于number的数放到数组右边),然后判断k与等于number区域的相对关系,如果k正好在等于number区域,那么数组第k小的数就是number,如果k在等于number区域的左边,那么我们递归对左边再进行上述过程,如果k在等于number区域的右边,那我们递归对右边再进行上述过程。
bfprt解法:
第一步:将数组每5个相邻的数分成一组,后面的数如果不够5个数也分成一组。至于为什么一组5个,大概是因为该算法由5个人提出。
第二步:对于每组数,我们找出这5个数的中位数,将所有组的中位数构成一个中位数数组。
第三步:再对这个中位数数组求中位数,此时所求出的中位数devide就是划分依据。
第四步:将devide传入partation过程,再进行常规求解。
//获取root数组中从begin位置到end位置的中位数 public static int getMedian(int[] root,int begin,int end) { if(begin>end) return -1; if(begin==end) return root[begin]; //先对数组进行排序 //insertionSort(root, begin, end); Arrays.sort(root,begin,end); int sum = begin+end; int mid = (sum/2) + (sum%2); return root[mid]; } //将root数组从begin到end的元素以5个为一组进行划分,并对组内求中位数 public static int medianofMedian(int[] root,int begin,int end) { int num = end-begin+1; int offset = num%5==0? 0:1; int range = num/5+offset; int[] median = new int[range]; for(int i = 0;i<range;i++) { int begin1 = begin+i*5; int end1 = begin1+4; median[i] = getMedian(root, begin1, Math.min(end, end1)); } return bfprt(median,0, range-1, range/2); } public static int bfprt(int[] root,int begin,int end,int k) { if(begin==end) return root[begin]; int divide = medianofMedian(root, begin, end); int[] index = patition(root, begin, end, divide); if(k>=index[0]&&k<=index[1]) return root[k]; else if(k<index[0]) { return bfprt(root, begin, index[0]-1, k); } else if(k>index[1]){ return bfprt(root, index[1]+1, end, k); } return -1; } public static int[] patition(int[] root,int begin,int end,int number) { int less = begin -1; int more = end+1; int cur = begin; while(cur<more) { if(root[cur]<number) { less++; swap(root, less, cur); cur++; } else if(root[cur]==number) { cur++; } else { more--; swap(root, cur, more); } } int[] a= {less+1,more-1}; return a; } public static void swap(int[] root, int a, int b) { int temp=root[a]; root[a]=root[b]; root[b]=temp; } public static void main(String[] args) { int[] arr = { 1,2,3,4,5,6,7,8,9,10 }; int a = bfprt(arr, 0, arr.length-1,4); System.out.print(a); }

浙公网安备 33010602011771号