——算法导论(Introduction to Algorithms, Third Edition)算法
//打印输出数组模块 public class PrintArrays { public static void printA(int []A) { for (int aInput : A) { System.out.print(aInput+ " "); } } }
//产生随机数组模块 import java.util.*; public class RandomArray { public static int[] randomArray( int num) { Random rad =new Random(System.currentTimeMillis()); int array[] = new int[num]; for (int i= 0 ; i<num ; i++) { array[i] = rad.nextInt(100); } return array; } }
//正常循环迭代实现 public class InsertSort02 { public static void main(String args[]) { int A[] = {1,9,6,8,4,5,3,7,2,0}; for (int j= 0; j<A.length-1 ; j++) { int key =A[j+1] ; int i= j; //关键性插入 while ((i >= 0)&&(key< A[i])) { A[i+1] = A[i]; i--; } A[i+1] = key; } PrintArrays.printA(A); } }
//递归实现 public class InsertSort03 { public static void main(String srgs[]) { //产生随机数组 int A[] =RandomArray.randomArray(8); insertSort(A, 0, A.length); //输出数组 PrintArrays.printA(A); } //插入排序最后一个参数 r 为数组长度,p 为数组起始位置。 public static void insertSort(int []A,int p, int r) { // if 用于控制递归终止 if (r >p) { r--; //递归拆解 insertSort(A ,p , r); int i = r-1; int key = A[r]; //位置插入关键 //边查找合适的插入位置,边挪动数组的元素 while (( i>=p) && (key <A[i])) { A[i+1] = A[i]; i--; } A[i+1] = key; } } }
//常规归并排序 public class MergeSort01 { public static void main(String args[]) { int A[] = RandomArray.randomArray(8); mergeSort(A, 0, A.length-1); //打印输出模块同上 PrintArrays.printA(A); } //归并排序(递归调用) public static void mergeSort(int A[], int p, int r) { if ( r>p) { int q= (p+r-1)/2; //方法形参传递 为值传递 ,数组形参传递的是引用地址 mergeSort(A, p, q); mergeSort(A, q+1,r); mergeArray(A, p, q, r); } } //合并子问题的解 模块 public static void mergeArray(int A[] , int p,int q,int r) { int n1 = q - p + 1; int 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 j =0; j< n1 ; j++) { R[j] = A[q+j+1]; } for (int k= 0 ,i=0 ,j=0; ((i<n1) || (j<n2))&&(k< r-p+1) ; k++) { if (i>= n1) { A[p+k] = R[j]; j++; } else if(j>= n2) { A[p+k] = L[i]; i++; //以上是其中一个数组遍历完的处理 } else if ( L[i]< R[j]) { A[p+k] = L[i]; i++; } else{ A[p+k] = R[j]; j++; } } } }
//归并排序与插入排序结合 public class MergeSort02 { public static void main(String args[]) { //随机数组的产生 int A[] = RandomArray.randomArray(128); PrintArrays.printA(A); System.out.println(); mergeSort(A, 0, A.length-1, 4); //输出 PrintArrays.printA(A); } //归并排序 参数说明: // p 为数组起始位置 r 为数组末尾位置 nk 为子数组插入排序长度 public static void mergeSort(int A[], int p, int r, int nk) { int q= (p+r-1)/2; if ((q-p+1) > nk) { //递归分解 mergeSort(A, p, q, nk); mergeSort(A, q+1,r, nk); } else { //分治算法 解决最小的子问题 //插入排序最后一个参数为数组长度 InsertSort03.insertSort(A,p ,q +1); InsertSort03.insertSort(A,q+1 ,r+1 ); } MergeSort01.mergeArray(A, p, q, r); //方法形参传递 为值传递 ,数组形参传递的是引用地址 //因为 数组传递引用地址的特性,解决了分治算法的合并子答案步骤 } }
//选择排序算法 public class SelectionAlgorithm01 { public static void main(String args[]) { int A[] = {1,9,6,8,4,5,3,7,2,0}; //选择算法 //变量 min 依次提取最小值 for ( int j=1 , k=0; j < A.length ; j++) { int min = A[j-1] ; int i = j; //变量 K 用于记录最小值的位置 while( i < A.length) { if( min >A[i]) { min = A[i]; k = i; } i++; } A[k] = A[j-1]; A[j-1] = min; } // 4 重复 PrintArrays.printA(A); } }
public class BubbleSort { //冒泡排序法 public void maoPaoPX(int[] arryA) { //将最大的依次 冒泡到最右边 for (var i=arryA.length; i>0;i--) { for (var j=0;j<i;j++) { if ((j+1)==arryA.length) { break; } if ( arryA[j] > arryA[j+1] ) { int temp = arryA[j+1]; arryA[j+1] =arryA[j]; arryA[j] =temp; } } } } }
//查找算法 public class LinearSearch { static final int NIL = -1 ; public static void main(String args[]) { int v = 8; int []A = {1,9,6,8,4,5,3,7,2,0}; //排序 A = InsertSort03.insertSort(A, A.length); PrintArrays.printA(A); System.out.println(); //线性查找 int j = linearSearch(A , v); System.out.println("j = "+ j); //二分法查找 j= binarySearch02(A , v, 1 ,A.length ,1 ) ; System.out.println("j = "+ j); /* j= binarySearch(A , v , true , 0, A.length-1); System.out.println("j = "+ j); */ } //二分法查找 public static int binarySearch02(int []A,int v , int left,int right ,int mid) { mid = (left+ right)/2; int aMid= mid -1; if (A[aMid] == v) { return mid; } else if( A[aMid] > v){ right = mid; }else { left = mid; } return binarySearch02(A , v ,left ,right ,mid); } //线性查找 public static int linearSearch(int []A, int v) { int i=1; int j=NIL; for (int atemp : A) { if( atemp == v) { j=i ; } i++; } return j; } }
public class BookTest2o3o7 { public static void main(String args[]) { int A[] = {2 , 4, 5,6, 8, 10}; int x= 17; System.out.println(bookTest2o3o7(A, x)); } /* 描述一个运行时间为@(nlgn) 的算法,给定n 个整数的集合S 和另外一个整数X , 该算法能 肯定S 中是否存在两个元素其和恰好为x的元素。 */ public static boolean bookTest2o3o7(int []A, int x) { if (A.length <=1) { return false; } int i=0; int j= A.length-1; while(i<j) { //x 与 A[i]+A[j] 比较。 //若 x 较大,则 i 增大 ,不然 j 减少,直到 i >= j 结束循环。 if (x ==(A[i] + A[j]) ) { return true; } else if( x > A[i] + A[j]){ i++; } else { j--; } } return false; } }