快排:經典快排、隨機快排

快速排序(Quicksort)是對冒泡排序的一種改進。

快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列

時間複雜度

當數據有序時,以第一個關鍵字爲基準分爲兩個子序列,前一個子序列爲空,此時執行效率最差。

而當數據隨機分佈時,以第一個關鍵字爲基準分爲兩個子序列,兩個子序列的元素個數接近相等,此時執行效率最好。

所以,數據越隨機分佈時,快速排序性能越好;數據越接近有序,快速排序性能越差。

空間複雜度

快速排序在每次分割的過程中,需要 1 個空間存儲基準值。而快速排序的大概需要 NlogN次的分割處理,所以佔用空間也是 NlogN(底數爲2)個。

算法穩定性

在快速排序中,相等元素可能會因爲分區而交換順序,所以它是不穩定的算法。

 

荷蘭國旗問題引出

給定一個數組arr, 和一個數num, 請把小於num的數放在數組的左邊, 等於num的數放在數組的中間, 大於num的數放在數組的
右邊。
要求額外空間複雜度O(1),時間複雜度O(N)

實現算法:

假設num=arr[arr.length-1],即取數組最後一個值進行比較。left、right分別爲左右區域的指針。

如果當前值小於num,則將left指針向前移動一位,然後當前值與left區域新增的一位交換;

如果當前值大於num,則將right指針向後移動一位,然後將當前值與right區域新增的一位進行交換;

如果當前值等於num,不進行交換操作,繼續向下遍歷;

if arr[index] < num:
    left++; swap(arr[index], arr[left]);
if arr[index] > num:
    right--; swap(arr[index], arr[right]);
else
    index++;

 

 

快排:將一個數組分成小於某值和大於某值的前後兩部分,再對前後兩部分分別使用快排。(分治思想)。

java代碼實現:

package quickSort;

import java.util.Arrays;
import java.util.Random;

/**
 * @ClassName QuickSortDemo
 * @Description TODO
 * @Author 
 * @Date 19-7-17 上午10:20
 **/
public class QuickSortDemo {
    public static void quickSort(int[] nums, int L, int R) {
        if (L < R) {
//            swap(nums, (int) (L+(Math.random()*(R-L+1))), R);  //此行代碼實現隨機快排
            int [] p = partition(nums, L, R);
            quickSort(nums, L, p[0] - 1);
            quickSort(nums, p[1] + 1, R);
        }

    }

    private static int[] partition(int[] nums, int L, int R) {
        int left = L - 1;
        int right = R;
        while (L < right) {
            if (nums[L] < nums[R]) {
                swap(nums, ++left, L++);
            } else if (nums[L] > nums[R]) {
                swap(nums, --right, L);
            }
            else
                L++;
        }
        swap(nums, right, R);
        return new int[] {left + 1, right};
    }

    private static void swap(int[] nums, int i, int i1) {
        int tmp = nums[i];
        nums[i] = nums[i1];
        nums[i1] = tmp;
    }


    public static void main(String[] args) {
        Random random = new Random();
        int[] data = new int[20];
        for (int i = 0; i < data.length; i++) {
            data[i] = random.nextInt(100);
        }
        System.out.println(Arrays.toString(data));
        System.out.println("************ quick sort: ***********");
        quickSort(data, 0, data.length - 1);
        System.out.println(Arrays.toString(data));
    }
}

經典快排是每次選擇最後一位進行比較,受數據分佈影響較大,隨機快排每次隨機選擇一位來進行比較,平均效率更高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章