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,否则为0
c %= 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);
}
}