合并排序——分治策略
来源:互联网 发布:windows安装淘宝镜像 编辑:程序博客网 时间:2024/06/08 02:51
1、分治法
将原问题划分成N个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。
2、合并排序
算法描述:
代码实现
<span style="font-size:18px;">package com.dataStructure;public class MergeSort {public void mergeSort(int[] A, int p, int r) {if(p<r) {int q=(int) Math.floor((p+r)/2);mergeSort(A, p, q);mergeSort(A, q+1, r);merge(A,p,q,r);}}public void merge(int[] A, int p, int q, int r) {int n1=q-p+1, n2=r-q;int[] L=new int[n1];int[] R=new int[n2];for(int i=0;i<n1;i++){L[i]=A[p+i];}for(int i=0;i<n2;i++){R[i]=A[q+i+1];}int i=0,j=0;for(int k=p; k<=r; k++){if ((i<L.length&&j<R.length)&&(L[i]<=R[j])) {A[k]=L[i];i++;continue;} if((i<L.length&&j<R.length)&&(L[i]>R[j])){A[k]=R[j];j++;continue;}if(i>=L.length&&j<R.length) {A[k]=R[j];j++;continue;}if (j>=R.length&&i<L.length) {A[k]=L[i];i++;continue;}}}public static void main(String[] args) {MergeSort mergeSort = new MergeSort();int[] A=new int[]{1,3,8,9,4,5,6,7,2};mergeSort.mergeSort(A, 0, A.length-1);System.out.println("success");}}</span>
3、大整数乘法
算法描述:
代码实现:
<span style="font-size:18px;">package com.bigInteger.util;public class IntegerString {public int string_to_num(String k) {return Integer.parseInt(k);}public String num_to_string(int intValue){return Integer.toString(intValue);}//在字符串str前添加s个零public String stringBeforeZero(String str,int s){String zeroStr="0";for(int i=1; i<s; i++)zeroStr=zeroStr+"0";return zeroStr+str;}//两个大整数字符串相加,超出计算机表示范围的数也能实现相加(本函数可以实现大整数加法运算)public String stringAddstring(String str1,String str2){//假定str1和str2是相等的长度,不相等时在前面自动补零,使两个字符串长度相等if (str1.length() > str2.length()) {str2 = stringBeforeZero(str2,str1.length() - str2.length());}else if (str1.length() < str2.length()) {str1 = stringBeforeZero(str1,str2.length() - str1.length());}String result="0";int flag=0;//前一进位是否有标志,0代表无进位,1代表有进位for(int i=str1.length()-1; i>=0; i--){int c=(str1.charAt(i)-'0')+(str2.charAt(i)-'0')+flag;flag = c/10;//c大于10时,flag置为1,否则为0c %= 10;//c大于10时取模,否则为其本身result=num_to_string(c)+result;}if (0 != flag) //最后一为(最高位)判断,如果有进位则再添一位result=num_to_string(flag)+result;return result.substring(0, result.length()-1);}/*两个大整数字符串相减,超出计算机表示范围的数也能实现相减(在这里比较特殊,第一个参数一定大于第二个参数,因为:a1*b0+a0*b1=(a1+a0)*(b1+b0)-(a1*b1+a0*b0) > 0 ,所以(a1+a0)*(b1+b0) > (a1*b1+a0*b0)这个函数的两个参数,第一个代表的其实就是(a1+a0)*(b1+b0),第二个代表的其实就是(a1*b1+a0*b0)所以本函数里不用考虑最终得到结果为负数的情况,至于计算有关大整数负数相乘的问题可以通过其他途径判断*/public String stringSubtractstring(String str1,String str2){//对传进来的两个数进行修剪,如果前面几位有0则先去掉,便于统一处理while('0'==str1.charAt(0)&&str1.length()>1){str1=str1.substring(1);}while('0'==str2.charAt(0)&&str2.length()>1){str2=str2.substring(1);}//使两个字符串长度相等if (str1.length() > str2.length()){str2 = stringBeforeZero(str2,str1.length() - str2.length());}String result="0";for(int i=str1.length()-1; i>=0; i--){int c=(str1.charAt(i)-'0')-(str2.charAt(i)-'0');if (c < 0) //当不够减时向前一位借位,前一位也不够位时再向前一位借位,依次如下{c +=10;int prePos = i-1; char preChar = str1.charAt(prePos);while ('0' == preChar) {str1=str1.substring(0, prePos)+"9"+str1.substring(prePos+1);prePos -= 1;preChar = str1.charAt(prePos);}char borrow=(char) (str1.charAt(prePos)-1);str1=str1.substring(0, prePos)+Character.toString(borrow)+str1.substring(prePos+1);}result=num_to_string(c)+result;}return result.substring(0, result.length()-1);}//在字符串str后跟随s个零public String stringFollowZero(String str,int s){String zeroStr="0";for(int i=1; i<s; i++)zeroStr=zeroStr+"0";return str+zeroStr;} //分治法大整数乘法实现函数public String IntMult(String x,String y)//递归函数{//对传进来的第一个数进行修剪,如果前面几位有0则先去掉,便于统一处理while ('0' == x.charAt(0)&&x.length()>1){x=x.substring(1);}//对传进来的第二个数进行修剪,如果前面几位有0则先去掉,便于统一处理while ('0' == y.charAt(0)&&y.length()>1){y=y.substring(1);}/*这里的f变量代表在两个数据字符串长度不想等或者不是2的指数倍的情况下,所要统一的长度,这样做是为了让数据长度为2的n次方 的情况下便于利用分治法处理*/int f=4;/*当两字符串中有任意一个字符串长度大于2时都要通过与上面定义的f值进行比较,使其达到数据长度为2的n次方,实现方式是在前面 补0,这样可以保证数据值大小不变*/if (x.length()>2 || y.length()>2) {if (x.length() >= y.length()) //第一个数长度大于等于第二个数长度的情况{while (x.length()>f) //判断f值{f*=2;}if (x.length() != f) {x = stringBeforeZero(x,f-x.length());y = stringBeforeZero(y,f-y.length());}}else//第二个数长度大于第一个数长度的情况{while (y.length()>f) //判断f值{f*=2;}if (y.length() != f) {x = stringBeforeZero(x,f-x.length());y = stringBeforeZero(y,f-y.length());}}} if (1 == x.length()) //数据长度为1时,在前面补一个0(这里之所以会出现长度为1的数据是因为前面对数据修剪过){ x=stringBeforeZero(x,1);}if (1 == y.length()) //数据长度为1时,在前面补一个0(这里之所以会出现长度为1的数据是因为前面对数据修剪过){y=stringBeforeZero(y,1);} if (x.length() > y.length()) //最后一次对数据校正,确保两个数据长度统一{ y = stringBeforeZero(y,x.length()-y.length());}if (x.length() < y.length()) //最后一次对数据校正,确保两个数据长度统一{x = stringBeforeZero(x,y.length()-x.length());}int s = x.length(); String a1="0",a0="0",b1="0",b0="0"; if( s > 1) { a1 = x.substring(0,s/2); a0 = x.substring(s/2); b1 = y.substring(0,s/2); b0 = y.substring(s/2); } String result;if( s == 2) //长度为2时代表着递归的结束条件 { int na = string_to_num(a1); int nb = string_to_num(a0); int nc = string_to_num(b1); int nd = string_to_num(b0); result = num_to_string((na*10+nb) * (nc*10+nd)); } else{//长度不为2时利用分治法进行递归运算 /*************************************************** 小提示: c = a*b = c2*(10^n) + c1*(10^(n/2)) + c0; a = a1a0 = a1*(10^(n/2)) + a0; b = b1b0 = b1*(10^(n/2)) + b0; c2 = a1*b1; c0 = a0*b0; c1 = (a1 + a0)*(b1 + b0)-(c2 + c0); ****************************************************/ String c2 = IntMult(a1,b1);// (a1 * b1) String c0 = IntMult(a0,b0);// (a0 * b0) String c1_1 = stringAddstring(a1,a0);// (a1 + a0) String c1_2 = stringAddstring(b1,b0);// (b1 + b0) String c1_3 = IntMult(c1_1,c1_2);// (a1 + a0)*(b1 + b0) String c1_4 = stringAddstring(c2,c0);// (c2 + c0) String c1=stringSubtractstring(c1_3,c1_4);// (a1 + a0)*(b1 + b0)-(c2 + c0) String s1=stringFollowZero(c1,s/2);// c1*(10^(n/2)) String s2=stringFollowZero(c2,s);// c2*(10^n) result = stringAddstring(stringAddstring(s2,s1),c0);// c2*(10^n) + c1*(10^(n/2)) + c0 }return result;}public static void main(String[] args) {IntegerString bigIntMul=new IntegerString();String r=bigIntMul.IntMult("1111111111999999999888888888555555555444444444777777777222222222333333333666666666","999999999888888888777777777444444444555555555666666666111111111222222222333333333");while('0'==r.charAt(0)&&r.length()>1){r=r.substring(1);}System.out.println(r);}}</span>3、快速排序
算法描述:
代码实现:
package com.dataStructure;public class QuickSort { //快速排序 public void quick_sort(int s[], int l, int r) { if (l < r) { //Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1 int i = l, j = r, x = s[l]; while (i < j) { while(i < j && s[j] >= x) // 从右向左找第一个小于x的数 j--; if(i < j) s[i++] = s[j]; while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数 i++; if(i < j) s[j--] = s[i]; } s[i] = x; quick_sort(s, l, i - 1); // 递归调用 quick_sort(s, i + 1, r); } } public static void main(String[] args) {QuickSort quickSort = new QuickSort();int[] A=new int[]{5,3,8,9,4,1,6,7,2};quickSort.quick_sort(A, 0, A.length-1);}}
0 0
- 合并排序——分治策略
- 分治——合并排序
- 分治算法—合并排序
- 分治策略—归并排序
- 递归与分治策略-----合并排序
- 算法中分治策略实现合并排序
- 分治策略之合并排序问题
- 003分治——合并排序
- 递归与分治策略-2.7合并排序(归并排序)
- 基础算法 —— 合并排序(分治法)
- 0004算法笔记——【分治法】合并排序
- 0004算法笔记——【分治法】合并排序
- 04算法笔记——【分治法】合并排序
- 算法笔记——【分治法】合并排序
- 0004算法笔记——【分治法】合并排序
- 0004算法笔记——【分治法】合并排序
- 算法分析——分治思想之合并排序
- 分治法合并排序
- STM32 读写保护功能及设置
- ACdream Andrew Stankevich's Contest(1)
- 利用cocos2dx 3.2开发消灭星星(七)关于星星的算法
- 黑马程序员——基础加强(jdk1.5新特性)
- SQL语句详解
- 合并排序——分治策略
- NYOJ 170 网络的可靠性
- MySql数据库的基本操作-修改表-删除约束
- [心情贴 ] 今天终于把数据库和编程语言连接起来了
- 使用ViewPager滑动Activity
- 通信算法之九:通信系统的链路级仿真思路
- 英文seo 网站内容的创建
- 输入n个整数,输出其中最小的k个——来自华为OJ平台测试基础篇
- git 撤销未提交的修改