2.分而治之
来源:互联网 发布:英伟达experience优化 编辑:程序博客网 时间:2024/06/07 06:25
算法设计方法之一——分而治之,模仿了法国皇帝拿破仑在1852年12月2日奥斯特里茨战役中采用的接触策略。 分而治之(divide-and-conquer)将问题的一个实例划分为两个或更多个较小的实例,一直持续划分实例指导规模小到可以轻松获得答案为止。是一种自顶向下的方法。
1. 二分查找
/** * 二分查找 * 基于非递减的有序数组 * @param s 非递减数组,查找区域 * @param x 查找值 * @return 返回查找值所在位置,如查找不到返回-1 */ public int binsearch(int[] s,int x){ int location =-1; int start = 0; int end = s.length-1; int mid; while(location==-1 && start<=end){ mid = (start+end)/2; if(s[mid]==x){ location =mid; }else if(s[mid]< x){ start = mid+1; }else{ end = mid-1; } } return location; }
2. 合并排序
两路合并(two-way merging),表示将两个有序数组合并为一个有序数组。合并排序即重复应用两路合并完成对数组的排序。
**此代码有错,还未调试成功,希望有大神可以提供意见** /** * 合并排序 * 将n个建排列为非递减序列 * @param S 排序后的有序数组cun'fan'f */ static int S[] = {}; /** * 两路合并 * 将两个有序数组合并为一个有序数组 **/ public void merge(int[] arr1,int[] arr2 ){ int i=0,j=0,k=S.length; Arrays.copyOf(S,k+arr1.length+arr2.length); while(i<arr1.length && j<arr2.length){ if(arr1[i]<arr2[j]){ S[k]=arr1[i]; i++; }else{ S[k]=arr2[j]; j++; } k++; } if(i<arr1.length){ System.arraycopy(S,k,arr1,arr1[i],arr1.length-i); } if(j<arr1.length){ System.arraycopy(S,k,arr2,arr2[j],arr2.length-j); } } /** * 分而治之方法,拆分要排序的数组 * 调用merge()方法,两辆排序 * @param args 要排序的数组 */ public void mergesort(int[] arr){ int len = arr.length; int [] left; int [] right; int devide; if(len>1){ devide = len/2; left = new int[devide]; System.arraycopy(arr,0,left,0,devide); right = new int[len-devide]; System.arraycopy(arr,devide,right,0,right.length); mergesort(left); mergesort(right); merge(left,right); } }
3. 快速排序
/** * 快速排序 * @param arr 要排序的数组 * @param start 数组起始下标 * @param end 数组结束下标 */ public void quicksort(int[] arr,int start,int end){ /** * 首先判断该数组长度是否大于1 */ if(start<end){ int i=start; int j=end; /** * 以起始值为基准,并且该位置即为一个坑 */ int x=arr[start]; while(i<j){ /** * 从倒序分别与基准值x比对,大于基准值则比对下一项 */ while(i<j && arr[j]>=x){ j--; } /** * 直至该项值小于基准值,将该值放入正序的第一个坑,并且此位置空出来成为了一个坑 */ if(i<j){ arr[i++]=arr[j]; } /** * 从正序开始分别与基准值比对,小于基准值则比对下一项 */ while(i<j && arr[i]<=x){ i++; } /** * 直至该项值大于基准值,将该值放入刚刚腾出来的坑,并且此位置空处理啊成为了一个坑 */ if(i<j){ arr[j--]=arr[i]; } } /** * 将基准值x放入最后空出来的一个坑 * 经过上面排序之后,该基准值x左边都是小于该值的项,右边都是大于该值的项 */ arr[i]=x; quicksort(arr,start,i-1); quicksort(arr,i+1,end); for(int l=0;l<arr.length;l++){ System.out.print(arr[l]+" "); } System.out.println(); } }
4. Strassen矩阵乘法算法
1969年,Strassen发表了一种算法,对于矩阵的计算,无论是乘法或者加减法,其时间复杂度都优于根据矩阵的定义去计算。
5. 大整数的算数运算
大整数,是指超出计算机硬件所能表示的整数范围。如果需要表示这样的大整数,就只能通过软件来表示和处理这些整数。
- 大整数的加减法及其他线性时间运算
可以使用一个整数数组来表示大整数,每个位置存储一个数位。例如:534127的存储,存储到数组S中
S[6]
S[5] |S[4]| S[3]| S[2]| S[1]| S[0]
—-|—–|——|—–|—–|—–
5 |3 |4 |1 |2 |7
线性运算:
u∗10m乘法
u/10m除法
umod10m求余
例如:534127=534∗103+127 - 大整数的乘法
567832=567∗103+832
9423723=9423∗103+723
按照分而治之的思想,一个n位的大整数u,可以表示为:
u=x∗10(n/2)+y
y(n/2位)
x(n−n/2位)
两个整数相乘:
u=x∗10m+y
z=w∗10m+z
u∗z=(x∗10m+y)(w∗10m+z)=xw∗102m+(xz+yw)∗10m+yz
该代码还待修正
/** * 大整数乘法 * @param u 整数1 * @param v 整数2 */ public int prod(int u,int v){ int x,y,w,z; int n = 6,m; if(u==0||v==0){ return 0; } else{ m =n/2; int pow = (int)Math.pow(10,m); x=u/pow; y=u%pow; w=v/pow; z=v%pow; return x*w*(int)Math.pow(10,2*m)+(x*z+y*w)*pow+y*z; } }
6. 确定阈(yu)值
最优阈值:n
递归需要消耗大量的计算机内存,例如Strassen矩阵算法中,当矩阵为一阶矩阵时,直接按矩阵定义计算乘积反而比调用分而治之发效率高,类似于这样,求最优阈值n,当n大于该阈值时调用某个方法,当n小于阈值时调用另一效率更高的方法,这样可以使运算效率更快。
阅读全文
0 0
- 2.分而治之
- 分而治之
- 分而治之
- 分而治之
- 分而治之算法
- 分而治之算法
- 解决之道:分而治之
- 分而治之策略
- 分而治之算法
- 编码 分而治之
- 分而治之算法
- 算法中的分而治之思想
- J2ME中的分而治之
- 算法——分而治之
- 分而治之与步步为营
- 多进程与分而治之
- 统一考虑与分而治之
- “分而治之”是一种艺术
- VC6.0 Release 版本下调试运行设置
- java mac系统下寻找 java 和jdk的安装路径
- zTree -- jQuery 树插件 使用方法与例子
- env: node: No such file or directory的解决办法
- java 图形用户界面设计 之 改变主题 示例代码
- 2.分而治之
- oracle查询优化之sql语句优化
- n个数里最小的k个
- 32 Three.js的材质的种类和共有属性
- [LockFree之美] 共享变量的并发读写
- Android Init进程
- [LockFree之美] 使用Hazard Version实现的无锁Stack与Queue
- oracle11g利用分区表进行查询性能的优化
- 使用Python xlrd与xlwt模块读写Excel