java——快速排序
阿新 • • 發佈:2019-02-15
快速排序
快速排序就是分割交換的排序方法,是目前公認的最佳排序方法,在最快以及平均情況下,時間複雜度為O(nlogn)。最壞情況(資料本身就有序)就是每次挑中的基準值不是最大就是最小,其時間複雜度為O(n^2);不穩定,在最差情況下的空間複雜度為O(n),而最佳情況下為O(nlogn)。快速排序法是平均執行時間最快的排序法。
快速排序的思想:它的原理和氣泡排序一樣,都是用交換的方式,不過它會現在資料中找一個基準,把小於這個基準的資料放在左邊,大於基準的放在右邊。再以同樣的方式處理兩邊的資料。
現定義兩個下標,low和high分別指向第一個和最後一個,low從前往後走,high從後往前走,一般第一次以第一個元素為基準:
把小於這個基準的資料放在左邊,大於基準的放在右邊:
比較完一趟,確定了選的基準的有序位置,且基準左邊的都比基準小,右邊的都比基準大;然後在再這個有序元素進行兩邊同樣的比較,直至所有的元素位置都確定了就排序完了。
動態示意圖:
1、遞迴法
/** * @ClassName TestDemo1 * @Description 快速排序 * @Author lzq * @Date 2018/10/27 21:24 * @Version 1.0 **/ public class TestDemo1 { public static void main(String[] args) { int[] array = {20,1,9,56,25,32,87,45,12,69,54,19}; System.out.println(Arrays.toString(array)); quickSort(array); System.out.println(Arrays.toString(array)); } /** * 快速排序 * @param array */ public static void quickSort(int[] array) { sort(array,0,array.length-1); } /** * 遞迴的排序資料 * @param array * @param start * @param end */ private static void sort(int[] array,int start,int end) { int once = once(array,start,end); if(once > start) { //排序左邊 sort(array,start,once-1); } if(once < end) { //排序右邊 sort(array,once+1,end); } } /** * 一趟快速排序 * @param array * @param start * @param end * @return */ private static int once(int[] array,int start,int end) { int tmp = array[start]; while(start < end) { while(start < end && array[end] >= tmp) { --end; } array[start] = array[end]; //把比基準tmp大的數字移到後面 while(start < end && array[start] <= tmp) { ++start; } array[end] = array[start]; //把比基準tmp小的數字移到前面 } array[start] = tmp; //把基準放在它該放的位置 return start; //返回基準的位置,後面分別在這個基準位置兩邊重複上面的操作 } }
執行結果:
[20, 1, 9, 56, 25, 32, 87, 45, 12, 69, 54, 19]
[1, 9, 12, 19, 20, 25, 32, 45, 54, 56, 69, 87]
2、非遞迴法
就是用棧的方式去實現:
不停的出棧入棧到最後把棧出空即可:
/** * @ClassName TestDemo2 * @Description 非遞迴實現快速排序 * @Author lzq * @Date 2018/10/27 21:49 * @Version 1.0 **/ public class TestDemo2 { public static void main(String[] args) { int[] array = {20,23,98,54,12,15,19,3,46,78,59,84}; System.out.println(Arrays.toString(array)); quickSort(array,0,array.length-1); System.out.println(Arrays.toString(array)); } /** * 利用棧非遞迴的排序資料 * @param array * @param start * @param end */ private static void quickSort(int[] array,int start,int end) { int[] stack = new int[array.length]; //一個數組實現的棧 int top = 0; int low = 0; int high = array.length-1; int once = once(array,low,high); //入棧 if(once > low+1) { //用以排序左邊 stack[top++] = low; stack[top++] = once-1; } if(once < high-1) { //用以排序右邊 stack[top++] = once+1; stack[top++] = high; } //出棧 while(top > 0) { high = stack[--top]; low = stack[--top]; once = once(array,low,high); if(once > low+1) { stack[top++] = low; stack[top++] = once-1; } if(once < high-1) { stack[top++] = once+1; stack[top++] = high; } } } /** * 一趟快速排序 * @param array * @param start * @param end * @return */ private static int once(int[] array,int start,int end) { int tmp = array[start]; while(start < end) { while(start < end && array[end] >= tmp) { --end; } array[start] = array[end]; //把比基準tmp大的數字移到後面 while(start < end && array[start] <= tmp) { ++start; } array[end] = array[start]; //把比基準tmp小的數字移到前面 } array[start] = tmp; //把基準放在它該放的位置 return start; //返回基準的位置,後面分別在這個基準位置兩邊重複上面的操作 } }
執行結果:
[20, 23, 98, 54, 12, 15, 19, 3, 46, 78, 59, 84]
[3, 12, 15, 19, 20, 23, 46, 54, 59, 78, 84, 98]