1. 程式人生 > >八大排序算法——快速排序(動圖演示 思路分析 實例代碼Java 復雜度分析)

八大排序算法——快速排序(動圖演示 思路分析 實例代碼Java 復雜度分析)

執行 不變 class 滿足 思想 圖片 image 例如 排序算法

一、動圖演示

技術分享圖片

二、思路分析

快速排序的思想就是,選一個數作為基數(這裏我選的是第一個數),大於這個基數的放到右邊,小於這個基數的放到左邊,等於這個基數的數可以放到左邊或右邊,看自己習慣,這裏我是放到了左邊,

一趟結束後,將基數放到中間分隔的位置,第二趟將數組從基數的位置分成兩半,分割後的兩個的數組繼續重復以上步驟,選基數,將小數放在基數左邊,將大數放到基數的右邊,在分割數組,,,直到數組不能再分為止,排序結束。

例如從小到大排序:

1. 第一趟,第一個數為基數temp,設置兩個指針left = 0,right = n.length,

  ①從right開始與基數temp比較,如果n[right]>基數temp,則right指針向前移一位,繼續與基數temp比較,直到不滿足n[right]>基數temp

  ②將n[right]賦給n[left]

  ③從left開始與基數temp比較,如果n[left]<=基數temp,則left指針向後移一位,繼續與基數temp比較,直到不滿足n[left]<=基數temp

  ④將n[left]賦給n[rigth]

  ⑤重復①-④步,直到left==right結束,將基數temp賦給n[left]

2. 第二趟,將數組從中間分隔,每個數組再進行第1步的操作,然後再將分隔後的數組進行分隔再快排,

3. 遞歸重復分隔快排,直到數組不能再分,也就是只剩下一個元素的時候,結束遞歸,排序完成

根據思路分析,第一趟的執行流程如下圖所示:

技術分享圖片

三、負雜度分析

1. 時間復雜度:

最壞情況就是每一次取到的元素就是數組中最小/最大的,這種情況其實就是冒泡排序了(每一次都排好一個元素的順序)

這種情況時間復雜度就好計算了,就是冒泡排序的時間復雜度:T[n] = n * (n-1) = n^2 + n;

最好情況下是O(nlog2n),推導過程如下:

遞歸算法的時間復雜度公式:T[n] = aT[n/b] + f(n)

技術分享圖片

所以平均時間復雜度為O(nlog2n)

2. 空間復雜度:

  快速排序使用的空間是O(1)的,也就是個常數級;而真正消耗空間的就是遞歸調用了,因為每次遞歸就要保持一些數據:
  最優的情況下空間復雜度為:O(log2n);每一次都平分數組的情況   最差的情況下空間復雜度為:O( n );退化為冒泡排序的情況 所以平均空間復雜度為O(log2n)

四、Java 代碼如下

import java.util.Arrays;
public class quick{
    public static void main(String[] args) {
        int[] arr = new int[]{10,6,3,8,33,27,66,9,7,88};
        f(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void f(int[] arr,int start,int end){
        //直到start=end時結束遞歸
        if(start<end){
            int left = start;
            int right = end;
            int temp = arr[start];
            
            while(left<right){
                
                //右面的數字大於標準數時,右邊的數的位置不變,指針向左移一個位置
                while(left<right && arr[right]>temp){
                    right--;
                }
                
                //右邊的數字小於或等於基本數,將右邊的數放到左邊
                arr[left] = arr[right];
                left++;
                ////左邊的數字小於或等於標準數時,左邊的數的位置不變,指針向右移一個位置
                while(left<right && arr[left]<=temp){
                    left++;
                }
                
                //左邊的數字大於基本數,將左邊的數放到右邊
                arr[right] = arr[left];
            }
            
            //一趟循環結束,此時left=right,將基數放到這個重合的位置,
            arr[left] = temp;
            System.out.println(Arrays.toString(arr));
            //將數組從left位置分為兩半,繼續遞歸下去進行排序
            f(arr,start,left);
            f(arr,left+1,end);
        }
    }
}

八大排序算法——快速排序(動圖演示 思路分析 實例代碼Java 復雜度分析)