今天晚上复习数据结构的排序算法,花了一晚上手撸了七种排序算法:冒泡、选择、插入、shell、堆排序、归并排序、快速排序……
现在已然是深夜十一点多,就姑且发个博客,贴上我所写的代码。对于每种排序的原理,由于实在想睡觉了,就不进行深入阐述,一切都在代码中。
注意:本人代码都经过对数器验证,可以保证正确性~
1、冒泡排序
/* …………冒泡排序………… */ public static int[] BubbleSort(int[] arr){ if(arr == null || arr.length<2){ return arr; } int size = arr.length; for(int i = 0; i<size;i++){ for(int j = 1;j<size-i;j++){ if(arr[j-1]>arr[j]){ swap(arr,j-1,j); } } } return arr; }
2、选择排序
/* …………选择排序………… */ public static int[] selectSort(int[] arr){ if(arr == null || arr.length <2){ return arr; } for(int i=0;i<arr.length-1;i++){ int min = i; for(int j=i+1;j<arr.length;j++){ min = arr[min] < arr[j] ? min:j; } swap(arr,i,min); } return arr; }
3、插入排序
/* ^…………插入排序………… */ public static int[] insertSort(int[] arr){ if(arr==null || arr.length<2){ return arr; } for(int i = 1;i<arr.length;i++){ for(int j =i-1;j>=0;j--){ if(arr[j]>arr[j+1]){ swap(arr,j,j+1); } } } return arr; }
4、shell排序
/* …………shell排序………… */ public static int[] shellSort(int[] arr){ if(arr == null || arr.length<2){ return arr; } int h =1; while (h<=arr.length/3){ h = h*3+1; } while (h>0){ for(int i =h;i<arr.length;i +=h){ for (int j = i-h;j>=0;j -=h){ if(arr[j] > arr[j+h]){ swap(arr,j,j+h); } } } h = (h-1)/3; } return arr; }
5、堆排序
/* …………堆排序………… */ public static void heapSort (int[] arr){ if(arr == null || arr.length<2){ return; } for(int i=0;i<arr.length;i++){ heapInsert(arr,i); } int heapSize = arr.length; swap(arr,0,--heapSize); while (heapSize>0){ heapify(arr,0,heapSize); swap(arr,0,--heapSize); } } public static void heapInsert(int[] arr,int index){ while (arr[index]>arr[(index-1)/2]){ swap(arr,index,(index-1)/2); index = (index-1)/2; } } public static void heapify(int[] arr,int index,int heapSize){ int left = index*2+1; while (left < heapSize) { int largest =left+1 < heapSize && arr[left+1] > arr[left] ? left+1 : left; largest = arr[index] > arr[largest] ? index : largest; if(index == largest){ break; } swap(arr,index,largest); index = largest; left = index*2+1; } }
6、归并排序
/* …………归并排序………… */ public static void mergeSort(int[] arr){ if(arr == null || arr.length<2){ return; } int size = arr.length; sortProcess(arr,0,size-1); } public static void sortProcess(int[] arr,int start,int end){ if(start == end){ return; } int mid = (start+end)/2; sortProcess(arr,start,mid); sortProcess(arr,mid+1,end); merge(arr,start,mid,end); } public static void merge(int[] arr,int start,int mid,int end){ int p1 = start; int p2 = mid+1; int[] arr1 = new int[end-start+1]; int index = 0; while (p1<=mid && p2 <=end){ arr1[index++]=arr[p1]<arr[p2] ? arr[p1++]:arr[p2++]; } while (p1<=mid){ arr1[index++]=arr[p1++]; } while (p2<=end){ arr1[index++]=arr[p2++]; } for(int i=0;i<arr1.length;i++){ arr[start+i]=arr1[i]; } }
7、快速排序
/* …………快速排序………… */ public static void quickSort(int[] arr){ if(arr == null || arr.length <2){ return; } quickSort(arr,0,arr.length -1); } public static void quickSort(int[] arr,int start,int end){ if(start<end){ swap(arr,start+(int)((end-start+1)*Math.random()),end); int[] p = partiton(arr,start,end); quickSort(arr,start,p[0]-1); quickSort(arr,p[1]+1,end); } } public static int[] partiton(int[] arr,int start,int end){ int less = start-1; int current = start; int more = end; while (current<more){ if(arr[current]<arr[end]){ swap(arr,++less,current++); }else if(arr[current]>arr[end]){ swap(arr,--more,current); }else { current++; } } swap(arr,more,end); return new int[] {less+1,more}; }
8、对数器
/* …………对数器……………… */ public static int[] RandomArray(int size,int value){ int[] arr = new int[(int)((size+1)*Math.random())] ; for(int i=0;i<arr.length;i++){ arr[i] = (int)((value+1)*Math.random())-(int)(value*Math.random()); } return arr; } public static void rightMathod(int[] arr){ Arrays.sort(arr); } public static boolean isEqual(int[] arr1,int[] arr2){ if(arr1 == null && arr2 == null){ return true; } if((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)){ return false; } if(arr1.length != arr2.length){ return false; } for(int i = 0;i<arr1.length;i++){ if(arr1[i] != arr2[i]){ return false; } } return true; } public static void swap(int[] arr,int i,int j){ if(arr == null || arr.length<2){ return; } int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } public static int[] copyArray(int[] arr){ int[] arr1 = new int[arr.length]; for(int i=0;i<arr.length;i++) { arr1[i] = arr[i]; } return arr1; } public static void printArray(int[] arr){ for(int i=0;i<arr.length;i++){ System.out.print(arr[i]+" "); } }
9、main函数
public static void main(String args[]){ int size = 100; int value = 10; int max = 100000; boolean succeed = true; for(int i =0;i<max;i++){ int[] arr = RandomArray(size,value); int[] arr1 = copyArray(arr); int[] arr2 = copyArray(arr); rightMathod(arr1); // BubbleSort(arr2); // selectSort(arr2); // insertSort(arr2); // shellSort(arr2); // heapSort(arr2); // mergeSort(arr2); quickSort(arr2); succeed = isEqual(arr1,arr2); if(succeed == false){ System.out.println("origin array: "); printArray(arr); System.out.println("right array: "); printArray(arr1); System.out.println("error Array: "); printArray(arr2); break; } } System.out.println(succeed ? "nice!" : "error!"); }
最后
最后,简单总结一下各种排序的稳定性以及时间复杂度。n^2 的是冒泡(稳定),选择(不稳定),插入(稳定)n*logn的是堆排(不稳定),归并(稳定),快排(稳定)shell 排序。。。时间复杂度这个不好说,不过是不稳定的。
晚安大家~