参考http://blog.csdn.net/column/details/algorithm-easyword.html下载的
MoreWindows白话经典算法之七大排序第2版,
下图中“类别”有误,别管它
快速排序对100000长的数组居然java.lang.StackOverflowError!!!
整理到归并算法:
package p1; import java.util.Date; public class SortAlgorithm { //----------------------------------------heap sort----------------------------------------- //原始的Fix up, 类似于基于后移的插入排序 public static void minHeapFixup(int [] heap, int i){ int temp = heap[i]; int p = (i - 1)/2; while(i > 0){ if(heap[p] <= temp) break; heap[i] = heap[p];//将比temp大的元素往下移 i = p; p = (i - 1)/2; } heap[i] = temp; } //基于交换的Fix up public static void minHeapFixup1(int [] heap, int i){//把i的元素向上调整, heap已经是一个堆了 int p;//pos的父节点 for(p = (i-1)/2 ; p>=0 && heap[p] > heap[i] ; i=p, p=(i-1)/2){ int temp = heap[p]; heap[p] = heap[i]; heap[i] = temp; } } // Fix down public static void minHeapFixdown(int [] heap, int i, int n){//把i元素向下调整,总节点数为n int temp = heap[i]; int c = 2 * i + 1;//child 初始为 left child while(c < n){ if((c+1) < n && heap[c] > heap[c+1]){//right child更小,则取right child, 别忘了(c+1) < n c++; } if(heap[c] >= temp) break; heap[i] = heap[c]; i = c; c = 2 * i + 1; } heap[i] = temp; } //将数组建成Heap: 从最后一个节点的父亲开始( (n-1 - 1)/2 = n/2 - 1)直到根节点, 依次Fixdown //堆排序: minHeap排序后是降序, NOT稳定, 空间复杂度o(1),因为没用到递归 public static void heapSort(int [] arr, int n){ int i; //1 先把arr 转换为heap: 从最后一个节点的父亲开始直到根节点,Fixdown for(i = n/2 - 1; i>=0; i--){ minHeapFixdown(arr, i, n); } //2 依次交换堆首和堆尾, Fixdown for(i = n-1; i>0; i--){ int temp = arr[i]; arr[i] = arr[0]; arr[0] = temp; minHeapFixdown(arr, 0, i); } } //----------------------------------------quick sort----------------------------------------- //快速排序, NOT稳定的 , 空间复杂度??? public static void quickSort(int [] arr, int n){ //原始快速排序 调用Divid //quickSortDivid(arr, 0, n-1); //简化的 quickSort1(arr,0,n-1); } //快速排序 简化版 public static void quickSort1(int [] arr, int f, int t){ if(f<t){ int pivot = arr[f], l=f, r=t; while(l < r){ while(l<r && arr[r] >= pivot){//注意是 >= 不是> r--; } if(l<r) { arr[l++] = arr[r]; } while(l<r && arr[l] < pivot){ l++; } if(l<r) { arr[r--] = arr[l]; } }//循环结束时l==r arr[l] = pivot;//别忘了最终放pivot quickSort1(arr,f,l-1); quickSort1(arr,l+1,t); } } //原始快速排序__子函数分治 public static void quickSortDivid(int [] arr, int f, int t){ if(f < t){ int pos = quickSortAdjust(arr, f, t);//pos位置上的元素已是在其最终位置上了 quickSortDivid(arr, f, pos-1); quickSortDivid(arr, pos+1, t); } } //原始快速排序__子函数,将首元素调整到 最终位置 public static int quickSortAdjust(int [] arr, int l, int r){//left, right int pivot = arr[l]; while(l < r){ while(l<r && arr[r] >= pivot){//如果右边找不到比pivot小的值,那么right就会递减至等于left,注意如果是 && arr[r] > pivot会导致{3, 4, 1, 3, 2}出错 r--; } if(l<r) { arr[l++] = arr[r];//将比pivot大的值移到left } while(l<r && arr[l] < pivot){//注意不是 && arr[r] <= pivot!!! l++; } if(l<r) { arr[r--] = arr[l]; } }//循环结束时l==r arr[l] = pivot;//别忘了最终放pivot return l; } //----------------------------------------merge sort----------------------------------------- //归并排序, 稳定的, 对于second test data 性能很好,空间复杂度O(N) public static void mergeSort(int [] arr, int n){ int [] tempArr = new int [n]; int first =0, last = n-1; mergeSortDivid(arr, first, last, tempArr); } //归并的子函数__递归分解 public static void mergeSortDivid(int [] a, int first, int last, int [] tempArr){ if(first < last){//若从 first到last长度为1则什么都不做 int mid = (first + last)/2; mergeSortDivid(a, first, mid, tempArr); mergeSortDivid(a, mid+1, last, tempArr); mergeSortMerge(a, first, mid, last, tempArr); } } //归并的子函数__归并 public static void mergeSortMerge(int [] a, int first, int mid, int last, int [] tempArr){ int l1 = mid, l2 = last;//两个有序数组的末尾 int i = first, j = mid+1, k = 0; while(i<=l1 && j<=l2){//不是i<l1 && j<l2以防从first到last长度为2的情况 if(a[i] < a[j]){ tempArr[k++] = a[i++]; }else{ tempArr[k++] = a[j++]; } } while(i<=l1){ tempArr[k++] = a[i++]; } while(j<=l2){ tempArr[k++] = a[j++]; } //再把 排序后的元素拷回原数组 for(i=0; i<k; i++){ a[first + i] = tempArr[i];//注意不是a[i] = tempArr[i] } } //----------------------------------------select sort----------------------------------------- //选择排序,选择是NOT稳定的,如3 3 2, 对于first test data真糟糕, 即使最好情况下仍然是O(n的平方) public static void selectSort(int [] arr, int n){ int i, j; for(i=0; i<n; i++){ int minPos = i; //每次从i到n-1中找到最小值,将其与i进行互换 for(j=i+1; j<n; j++){ if(arr[j] < arr[minPos]){ minPos = j; } } if(minPos > i){ int temp = arr[i]; arr[i] = arr[minPos]; arr[minPos] = temp; } } } //----------------------------------------shell sort----------------------------------------- //原始的希尔排序 希尔是 NOT稳定的 public static void shellSort(int [] arr, int n){ int i,j,k, gap; for(gap = n/2; gap>0; gap/=2){//步长每次减半 for(i = 0; i<gap; i++){//从0到gap-1共有gap个分组 //每个分组内进行insert sort for(j = gap; j<n; j+=gap){ if(arr[j-gap] > arr[j]){ int temp = arr[j]; for(k = j-gap; k>=0 && arr[k] > temp; k-=gap){//k>=0要写在&&之前 arr[k+gap] = arr[k]; } arr[k+gap] = temp; } } } } } //代码简洁后的希尔排序,对于second test data性能出奇得好! public static void shellSort2(int [] arr, int n){ int i, j, gap; for(gap = n/2; gap>0; gap /=2){ for(j = gap; j<n; j++){//从gap到n-1共n-gap个元素 if(arr[j-gap] > arr[j]){ //改用exchange实现的insert sort for(i = j-gap; i>=0 && arr[i]>arr[i+gap]; i-=gap){ int temp = arr[i]; arr[i] = arr[i+gap]; arr[i+gap] = temp; } } } } } //----------------------------------------insert sort----------------------------------------- //插入排序_后移, 插入是稳定的 public static void insertSortBackWhileSearch(int [] arr, int n){ int i,j; for(i=1; i<n; i++){ if(arr[i] < arr[i-1]){//1 发现 逆序 int temp = arr[i];//插入值 //2 搜索 插入位置, 与此同时, 后移一位,腾出位置; 因为要后移,所以是从i-1到 0倒着搜索 for(j=i-1; j>=0 && arr[j]>temp; j--){ arr[j+1] = arr[j]; } //3 搜索和后移都结束了,插入 arr[j+1] = temp; } } } //插入排序_交换 public static void insertSortExchange(int [] arr, int n){ int i,j; for(i=1; i<n; i++){ //每一次i循环结束,使得从0到i都是顺序的,下一次循环判断从0到i+1是否存在逆序,如果逆序就交换 ,类似于冒泡! for(j=i-1; j>=0 && arr[j]>arr[j+1]; j--){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } //----------------------------------------bubble sort----------------------------------------- //冒泡排序_使用了两个优化技术 , 冒泡是稳定的 public static void bubbleSort(int [] arr, int n){ int i,j; boolean flag = true; int k = n-1; int pos = n-1; while(k>0){ flag = false; for(j = 0; j < k; j++){ if(arr[j] > arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; pos = j;//优化2 flag = true;//优化1 } } k = pos;// if(!flag) break; } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub long t1,t2; t1 = (new Date()).getTime(); int [] arr = new int[100000]; int i,j; //1st test data for(i=0;i<100;i++){ arr[i] = 100-i; } for(i=100;i<100000;i++){ arr[i] = i+100; } //2nd test data // for(i=0;i<100;i++){ // arr[i] = 100-i; // } // for(i=100;i<100000;i++){ // //arr[i] = i+100; // arr[i] = 100000-i; // } //3rd test data for quick sort // for(i=0;i<6000;i++){ // arr[i] = 6000-i; // } // for(i=2000;i<4000;i++){ // if(i%2==0){ // arr[i] = arr[i+1]; // } // } System.out.println("before--------"); //for 1st and 2nd test data for(i=0;i<100;i++){ System.out.print(arr[i]+" "); } System.out.println(); for(i=99901;i<100000;i++){ System.out.print(arr[i]+" "); } System.out.println(); //for 3rd test data // for(i=0;i<100;i++){ // System.out.print(arr[i]+" "); // } // System.out.println(); // for(i=5900;i<6000;i++){ // System.out.print(arr[i]+" "); // } // System.out.println(); // bubbleSort(arr,100000);//10 //22062 // insertSortBackWhileSearch(arr,100000);//10 //17328 // insertSortExchange(arr,100000);//11 //29830 // shellSort(arr,100000);//16 //9114 // shellSort2(arr,100000);//15 //25 // selectSort(arr,100000);//14940 // mergeSort(arr,100000);//25 //26 // quickSort(arr,6000);// 41 //quickSort(arr,6395)就会java.lang.StackOverflowError heapSort(arr,100000);// 24 //23 //---------temp test for quick sort // int [] bb = {3, 4, 1, 3, 2}; // quickSortAdjust(bb, 0, 4); // for(int b:bb){ // System.out.println("--"+b); // } // t2 = new Date().getTime(); System.out.println("time used:"+(t2-t1)); //---------temp test for heap sort // int [] bb = {3, 4, 1, 3, 2}; // heapSort(bb,5); // for(int b:bb){ // System.out.println("--"+b); // } System.out.println("after--------"); //for 1st and 2nd test data for(i=0;i<100;i++){ System.out.print(arr[i]+" "); } System.out.println(); for(i=99901;i<100000;i++){ System.out.print(arr[i]+" "); } System.out.println(); //for 3rd test data // for(i=0;i<100;i++){ // System.out.print(arr[i]+" "); // } // System.out.println(); // for(i=5900;i<6000;i++){ // System.out.print(arr[i]+" "); // } // System.out.println(); } }