今天咱們看看快速排序,其實咱們是在大二上學期上的數據結構,如今基本上忘的差很少了,最近這兩年一直在作應用,因此這個面試官給我敲響了警鐘,雖說我面試的結果不怎麼樣,可是個人收穫仍是不少的,在這裏與你們分享一下。但願你們在面試以前,必定要看看咱們經常使用的算法,這是常常考的,還有就是面試官會問你算法複雜度,這是個很頭疼的問題,一開始學的時候就不會,但願哪一個大神有好的算算法複雜度的方法,請指教。
java
下面咱們看看快速排序的思想 和 java實現
面試
快速排序是對冒泡排序的一種改進。
算法
不穩定,時間複雜度 最理想 O(nlogn)最差時間O(n^2)數組
基本思想 : 利用的是 分治法的基本思想數據結構
經過一躺排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一不部分的全部數據都要小,而後再按次方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列。ide
咱們看一下快速排序的步驟:
ui
一趟快速排序的算法是:spa
1) 設置兩個變量 i 和 j 排序開始的時候, i = 0 j = N -1 (N 爲數組的長度)3d
2)選取基準元素,一般選取數組的第一個元素爲基準元素 key = arr[0]blog
3) 從 j 開始向前搜索,即由後向前(j--)搜索 ,找到第一個小於key的值 arr[j] 將arr[i] 和 arr[j]進行交換 而後中止
4) 從 i 開始向後搜索,即由前向後(i++)搜索, 找到第一個大於key的值 arr[i] 將arr[i] 和 arr[j] 進行交換 而後中止
5) 重複第 3 、四、 5步 直到 i == j 中止
這樣第一趟排序就完成了,這樣就保證了 基準元素左面的元素都比基準元素小 ,基準元素右面的元素都比基準元素大 ,下面進行的就是在分別對基準元素左邊的(元素都比基準小)數組進行排序(和第一趟排序步驟同樣)和右邊的數組進行排序。(遞歸)
java 算法實現:
package cn.edu.ytu.botao.java.sort; /** * * @author botao * */ public class Quicksort { public static void main(String[] args) { //須要排序的數組 arr 並初始化數組 int[] arr = {49,38,65,97,76,13,27}; Quicksort quicksort = new Quicksort(); quicksort.sort(arr, 0, arr.length-1); quicksort.print(arr); } /** * 將數組元素輸出 * @param arr */ public void print(int[] arr) { for (int i = 0; i < arr.length; i++) { if (i == arr.length-1) { System.out.print(arr[i]); }else { System.out.print(arr[i] + ","); } } } /** * * @param arr 要排序的數組 * @param low 開始的下標 * @param high 結束的下標 */ public void sort(int[] arr ,int low, int high) { //令 i = 開始的下標 令 j = 結束的下標 int i = low; int j = high; //遞歸的終止條件 if (i > j) { return ; } /** * 注意: 遞歸終止的條件必定要在選取基準元素以前 不然會出現下標越界 */ //基準元素 通常爲數組的第一個元素 int key = arr[low]; /** * 第一趟排序開始 */ //進行第一趟排序 while (true) { //從後面往前走 j-- while (j > i) { //基準元素 大於 後面的元素 因此要將前面的元素和後面的元素進行交換 if (arr[j] < key) { int temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; break; //完成一次循環 退出 }else { j--; } } //從前面日後走 while (j > i) { //基準元素 小於 前面的元素 因此要將後面的元素與前面的元素進行交換 if (arr[i] > key) { int temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; break; //完成一次循環 退出 }else { i++; } } //完成一趟循環 退出 if (j == i) { break; } } /** * 第一趟排序結束 */ //完成第一趟循環後進行重複性遞歸 //分而治之的左面的數組 sort(arr, low, i-1); //分而治之的右面的數組 sort(arr, i+1, high); //遞歸要加終止條件 在上面 } }