最坏情况为线性时间的选择算法---算法导论学习笔记(2)
2016-11-08 21:46
465 查看
前面学习了在期望时间内选择任意顺序统计量,这次就运用这种顺序统计量的选择去实现线性时间的选择。
1.算法概述
以上就是整个算法的过程,看起来比较的笼统,因为真正涉及到实现的时候有挺多的细节问题要注意到。尤其是在第(5)步递归调用的时候,需要控制好边界条件和分区函数的思路一样。
2.Java实现
在public static int partition(int[] arr,int start,int end,int key),public static int select(int[] arr,int left,int right,int k)这两个函数的思路我借鉴了算法之线性时间选择(最坏情况下)这位博主的思路,我觉得相比书上的partition,这个代码更加简洁,而且得到的分区效果相同。不过相应我没看懂的地方或者我觉得有问题的地方做了修改(原谅我水平低).值得一提的是原select函数中,应该是元素数量小于75的直接进行插入排序后返回结果,这样做是对的,但是我比较急于测试,所以改成了小于分组大小时直接排序输出。感谢原博主。
3.分析
对于大于中位数的中位数x,大于x的元素个数至少有:
3(⌈1/2⌈n/5⌉⌉−2)⩾3n/10−6
那么,递归至多作用于(7n/10+6)个元素。
算法中的
第(3)步时间复杂度为T(⌈n/5⌉)
第(5)步的时间复杂度为T(7n/10+6)
我们可以得到算法的总时间复杂度为
T(n)≤T(⌈n/5⌉)+T(7n/10+6)+O(n)
假设一个任意常数C,使得T(n)≤cn
又假设O(n)的上界为an
那么带入c,a得到:
T(n)⩽9cn/10+7c+an=cn+(−9n/10+7c+an)
只需要证明: −9n/10+7c+an⩽0 即可
该不等式等价于:c⩾10a(n/(n−70))
所以当n>140时,c⩾20a这样就可以满足不等式。
因此最坏情况下选择算法的运行时间是线性的。
在边界条件的调试中花了不少的时间,感觉一开始就对整个算法的理解不是很清楚,更别说什么复杂度分析了,所以说明还是基本功不太扎实。
1.算法概述
1.将集合分成ceil(n/5)个组,即每个组中的元素都为5,最后一组元素数量为n mod 5 2.对每个组分别使用插入排序,并寻找出每个组的中位数。 3.每个组的中位数形成数量为ceil(n/5)的集合,在此集合内再求其中位数,即中位数的中位数,记为x。(这里就要再次递归调用select函数) 4.使用分区函数partition(就是上次笔记里学习到的partition分区),得到索引i,索引位置之前的低分区要比索引位置之后的高分区数量x小1 5.如果i=k,则返回x;如果i<k,则递归调用低分区(left,i-1,k);如果i>k,则递归调用高分区(i+1,right,k-i)
以上就是整个算法的过程,看起来比较的笼统,因为真正涉及到实现的时候有挺多的细节问题要注意到。尤其是在第(5)步递归调用的时候,需要控制好边界条件和分区函数的思路一样。
2.Java实现
public class SelectN { public static void InsertSort(int[] arr,int start,int end) { for(int i=start;i<=end;i++) { for(int j=start;j<i;j++) { if(arr[i]<arr[j]) { int x=arr[i]; for(int k=i;k>j;k--) { arr[k]=arr[k-1]; } arr[j]=x; break; } } } } public static int partition(int[] arr,int start,int end,int key) { int i=start; int j=end; while(true) { while(i<end&&arr[i]<=key) i++; while(arr[j]>key) j--; if(i>=j) break; swap(arr,i,j); } swap(arr,findk(arr,key),j); //交换最终结果 return j; } //获得元素的索引 public static int findk(int[] arr,int key) { for(int i=0;i<arr.length;i++) if(arr[i]==key) return i; return -1; } public static int select(int[] arr,int left,int right,int k) { if(right-left<5) { InsertSort(arr,left,right); return arr[left + k - 1]; } int group=(right-left+5)/5; for(int i=0;i<group;i++) { int l=left+i*5; int r; if(left+i*5+4>right) r=right; else r=left+5*i+4; InsertSort(arr,l,r); swap(arr,left+i,(r+l)/2); //将中位数都放在第一组集合中 } InsertSort(arr,left,left+group-1); //对中位数进行排序 int line=select(arr,left,left+group-1,(group+1)/2); int lower=partition(arr,left,right,line); //得到中位数的中位数分区后的索引 if(k==lower) //若索引等于k,则直接返回 return arr[lower]; else if(k<=lower-1) return select(arr,left,lower-1,k); else return select(arr,lower+1,right,k-lower);//k-lower的意思是在高分区中k(作为整体中)的位置 } public static void swap(int[] arr,int i,int j) { int temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } public static void main(String...args) { int[] arr={22,3,1,55,2,53,552,62,35,261,12,5125,3,42,1,23,5,26,4,7,68,4}; // System.out.println(select(arr,0,arr.length-1,4)); for(int i=1;i<arr.length;i++) { System.out.println(select(arr,0,arr.length-1,i)); } } }
在public static int partition(int[] arr,int start,int end,int key),public static int select(int[] arr,int left,int right,int k)这两个函数的思路我借鉴了算法之线性时间选择(最坏情况下)这位博主的思路,我觉得相比书上的partition,这个代码更加简洁,而且得到的分区效果相同。不过相应我没看懂的地方或者我觉得有问题的地方做了修改(原谅我水平低).值得一提的是原select函数中,应该是元素数量小于75的直接进行插入排序后返回结果,这样做是对的,但是我比较急于测试,所以改成了小于分组大小时直接排序输出。感谢原博主。
3.分析
对于大于中位数的中位数x,大于x的元素个数至少有:
3(⌈1/2⌈n/5⌉⌉−2)⩾3n/10−6
那么,递归至多作用于(7n/10+6)个元素。
算法中的
第(3)步时间复杂度为T(⌈n/5⌉)
第(5)步的时间复杂度为T(7n/10+6)
我们可以得到算法的总时间复杂度为
T(n)≤T(⌈n/5⌉)+T(7n/10+6)+O(n)
假设一个任意常数C,使得T(n)≤cn
又假设O(n)的上界为an
那么带入c,a得到:
T(n)⩽9cn/10+7c+an=cn+(−9n/10+7c+an)
只需要证明: −9n/10+7c+an⩽0 即可
该不等式等价于:c⩾10a(n/(n−70))
所以当n>140时,c⩾20a这样就可以满足不等式。
因此最坏情况下选择算法的运行时间是线性的。
在边界条件的调试中花了不少的时间,感觉一开始就对整个算法的理解不是很清楚,更别说什么复杂度分析了,所以说明还是基本功不太扎实。
相关文章推荐
- 《算法导论》读书笔记之第9章 中位数和顺序统计学 最坏情况是线性时间的选择算法
- 最坏情况为线性时间的选择算法之Python实现
- CLRS 9.3最坏情况为线性时间的选择算法
- 最坏情况为线性时间的选择算法
- 最坏情况下的线性时间的选择算法
- 算法导论:第9章 中位数和顺序统计量_2最坏情况为线性时间的选择算法
- 算法之分治——最坏情况线性时间的选择
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.
- 第九章中位数和顺序统计学 之 “寻找第i小元素之最坏情况线性时间的选择 最坏运行时间就为O(n)算法”
- 《算法导论》笔记 第9章 9.3最坏情况线性时间选择
- 最坏情况为线性时间的选择算法
- 算法导论第9章最坏情况为线性时间的选择算法
- 算法之线性时间选择(最坏情况下)
- (基于Java)算法之最坏情况下的线性时间选择
- 麻省理工算法导论学习笔记(5)----线性时间排序
- 【算法导论】学习笔记——第8章 线性时间排序
- 算法导论 最坏情况为线性时间的选择算法 9.3-8 9.3-9
- 最坏情况为线性时间的选择算法
- <算法导论>第九章3 最坏情况线性时间的选择
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.