快速排序思想:在partition中,首先以最右边的值做为划分值x,分别维护小于x的区间,等于x的区间,以及大于x的三个区间,最后返回划分值的左边界和右边界.时间复杂度为O(nlogn).算法
public class QuickSort { public static void quickSort(int[] arr) { if(arr == null || arr.length < 2) return ; sortProgress(arr, 0 , arr.length - 1); } public static void sortProgress(int[] arr, int L, int R) { if(L < R) { //随机取L到R之间的一个数与R交换. swap(arr, L + (int)(Math.random() * (R - L + 1)), R); //p数组的大小为2,p[0]表示划分值的左边界,p[1]表示划分值的右边界. int[] p = partition(arr, L, R); sortProgress(arr, L, p[0] - 1); sortProgress(arr, p[1] + 1, R); } } public static int[] partition(int[] arr, int L, int R) { int less = L - 1; int more = R; while(L < more) { if(arr[L] < arr[R]) { swap(arr, ++less, L++); }else if(arr[L] > arr[R]) { swap(arr, --more, L); }else { L++; } } swap(arr, more, R); //返回划分值的左边界和右边界 return new int[] {less + 1, more}; } public static void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } public static void main(String[] args) { int[] arr = new int[]{123,45,767,343,654,2,66,88}; System.out.print("原始数组:"); for(int i = 0; i < arr.length; i++) if(i != arr.length - 1) System.out.print(arr[i] + " "); else System.out.println(arr[i]); quickSort(arr); System.out.print("快速排序后:"); for(int i = 0; i < arr.length; i++) if(i != arr.length) System.out.print(arr[i] + " "); else System.out.println(arr[i]); } }
运行结果:api
堆排序思想:在构建最大堆堆的过程,每次向上调整,只需和父节点进行比较,构建堆的时间复杂度为O(n),在堆排序的过程当中,取堆顶元素与最后一个元素交换,而后堆顶元素向下调整,维护最大堆,最终便可完成排序.时间复杂度为O(nlogn).数组
public class HeapSort { 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 size = arr.length; swap(arr, 0, --size); while(size > 0) { heapify(arr, 0, size); swap(arr, 0, --size); } } 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 size){ int left = 2 * index + 1; while(left < size){ int largest = left + 1 < size && arr[left + 1] > arr[left]? left + 1: left; largest = arr[index] > arr[largest] ? index: largest; if(largest == index) { break; } swap(arr, index, largest); index = largest; left = 2 * index + 1; } } public static void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } public static void main(String[] args) { int[] arr = new int[] {3,66,65,43,213,76,66,23}; System.out.print("原始数组:"); for(int i = 0; i < arr.length; i++) if(i != arr.length - 1) System.out.print(arr[i] + " "); else System.out.println(arr[i]); heapSort(arr); System.out.print("堆排序后:"); for(int i = 0; i < arr.length; i++) if(i != arr.length - 1) System.out.print(arr[i] + " "); else System.out.println(arr[i]); } }
运行结果:
总结
快速排序是不稳定的。算法时间复杂度O(nlogn)
堆排序是不稳定的。算法时间复杂度O(nlogn)。less