快速排序

引用:本篇内容整理自王争老师《数据结构与算法之美》一书

核心思想

快速排序又成为快排(QuickSort),它主要利用分治和递归思想。
快排时间复杂度是O(nlogn),空间复杂度是O(1)。
假设有一个数组下标从 p 到 r :
首先选择任意一个数据做为基准点pivot,遍历 p 到 r 之间的数据,将小于pivot的数据放到左边,大于pivot的数据放到右边,最后把pivot放到中间。经过这个过程,原数组就变成了以pivot为分界点,左边是小于pivot的数,右边是大于pivot的数。
然后根据递归思想,我们将左边和右边数据进行递归调用排序方法,直到要排序数组区间为1时,说明数组已经有序了。
利用伪代码表示排序过程:

伪代码:
quick_sort(int[] array) {
	quick_sort_c(array, 0, array.length - 1);
}

quick_sort_c(int[] array, int p, int r) {
		if p >= r return;
		//排序后返回pivot分区点位置
		q = partition(array, p, r);
		//分区点左边数据递归排序
		quick_sort_c(array, p, q - 1);
		//分区点右边数据递归排序
		quick_sort_c(array, q + 1, r)
} 

partition(int[] array, p, r) {
		//通常选取左右边元素做为基准元素
		pivot = array[r];
		//使用下标 i 将数据分为两部分
		//下标 p 到 i - 1 部分为小于基准点pivot的数据,称为已处理区间
		//下标 i 到 r 成为未处理区间
		//每次从 i 到 r中选取一个数据array[j] 与pivot比较
		//如果小于pivot,则将array[j]加入到已处理区间尾部,也就是array[i]的位置
		i = p;
		for(j = p; j < r; j++) {
			if (array[j] < pivot) {
				//交换位置
				swap array[i] with array[j];
				i++;
			}
		}
		//将基准数据pivot放到中间位置
		swap array[i] with array[r];
		return i;
}

完整代码

public static void main(String[] args) {
        int[] arr = new int[]{1,5,2,8,6,3,12,9,7};
        quickSort(arr,0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 快速排序原理
     * 1、选取最后一位为基准点
     * 2、将小于基准点的数据放在左边
     * 3、最后将基准点数据放入中间位置
     * 4、基准点两边数据递归进行1、2、3步骤
     * @param arr 待排序数组
     * @param p 起始索引
     * @param r 终点索引
     */
    public static void quickSort(int[] arr, int p, int r) {
        if(p >= r) {
            return;
        }
        //将数组排序,返回中间基准点数据位置
        int q = partition(arr, p, r);
        quickSort(arr, p, q - 1);
        quickSort(arr, q + 1, r);
    }

    /**
     * 原地分区排序
     * @param arr 数组
     * @param p 起始索引
     * @param r 终点索引
     * @return 基准点索引
     */
    private static int partition(int[] arr, int p, int r) {
        int pivot = arr[r];
        int i = p;
        for (int j = p; j < r; j++) {
            if (arr[j] < pivot) {
                swap(arr, i, j);
                i++;
            }
        }
        swap(arr, i, r);
        return i;
    }

    /**
     * 交换指定下标位置元素
     * @param arr 数组
     * @param s 下标
     * @param d 下标
     */
    private static void swap(int[] arr, int s, int d) {
        int temp = arr[s];
        arr[s] = arr[d];
        arr[d] = temp;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值