快排:经典快排、随机快排

快速排序(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++;

快排:经典快排、随机快排_第1张图片

 

快排:经典快排、随机快排_第2张图片

 

快排:经典快排、随机快排_第3张图片

快排:将一个数组分成小于某值和大于某值的前后两部分,再对前后两部分分别使用快排。(分治思想)。

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));
    }
}

经典快排是每次选择最后一位进行比较,受数据分布影响较大,随机快排每次随机选择一位来进行比较,平均效率更高。

你可能感兴趣的:(leetcode,快排,荷兰国旗,java排序)