快排、堆排序
阿新 • • 發佈:2018-11-03
快排
經典快排
<=X | X | >X |
經典快排中間是一個數,左邊是小於等於X的範圍,右邊是大於X的數。可以用荷蘭國旗問題來改進快速排序。改進之後的快排:
<X | =X | >X |
荷蘭國旗問題快排演算法如下:
package test_01; import java.util.Arrays; public class NetherlandsFlag { public static int[] partition(int[] arr, int l, int r, int cur) { int less = l-1; int more = r+1; //int index = l; while (l < more) { if (arr[l] < cur) { swap(arr, ++less, l++); }else if (arr[l] > cur) { swap(arr, --more, l); }else { l++; } } return new int[] {less+1,more-1}; } public static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { int[] arr = {2,4,5,3,1,6,7,5,8,9}; int[] a = partition(arr,0,arr.length-1,5); System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(arr)); } }
- 時間複雜度O(N*logN),額外空間複雜度O(logN)。
另外一種寫法的快排演算法:
package test_01; import java.util.Arrays; public class QuickSort { 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 l, int r) { if (l < r) { int[] p = partition(arr, l, r); quickSort(arr, l, p[0]-1); quickSort(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 temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { int[] arr = {2,3,5,1,67,8,45}; quickSort(arr); System.out.println(Arrays.toString(arr)); } }
堆排序(堆排序非常重要)
- 堆結構的heapInsert與heapify
- 堆結構的增大和減少
- 如果只是建立堆的過程,時間複雜度為O(N)
- 優先順序佇列結構,就是堆結構
程式碼如下:
package test_01; import java.util.Arrays; public class HeadSort { 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 = index*2+1; while (left < size) { int largest = left+1 < size && arr[left+1] > arr[left] ? left+1:left; largest = arr[largest] > arr[index] ? largest:index; if (largest == index) { break; } swap(arr, largest, index); index = largest; left = index*2+1; } } public static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { int[] arr = {4,12,6,23,7,9,1}; heapSort(arr); System.out.println(Arrays.toString(arr)); } }
- 時間複雜度O(N*logN),額外空間複雜度O(1)。