排序算法 - 快速排序详解

基本思想

对于一组数据,选择一个基准元素(base),通常选择第一个或最后一个元素,通过一轮扫描,比base小的元素都在base左边,比base大的元素都在base右边,对左右子序列用相同的方法递归排序,直到序列中所有数据均有序为止。

快速排序,说白了就是给基准数据找其正确索引位置的过程。

在这里插入图片描述

思路图解

[19,97,09,17,01,08] 为例,以第一个元素19为base,定义左右两个指针 L和 R,分别从两端开始扫描。从右向左找比19小的数,替换L所在位置的元素。再从左往右找比19大的数,然后替换R所在位置的元素。重复此过程直至L和R重合(两个指针指向同一元素),base替换此元素,此时第一轮结束。再递归排序base左右两部分的元素。
在这里插入图片描述
首先R从后向前扫描,如果扫描到的值大于基准数据就让R减1,然后继续往前扫描,直到发现有元素比该基准数据的值小(如上图中08<=base),就将R位置的值赋值给L位置 ,结果如下:

在这里插入图片描述

然后交替移动L下标:L从前往后扫描,如果扫描到的值小于基准数据就让L加1,然后继续向后扫描,直到发现有元素大于基准数据的值(如上图97>=base),就再将L位置的值赋值给R位置的值,指针移动并且数据交换后的结果如下:

在这里插入图片描述
然后交替移动R下标,向前移动,直到扫描到小于基准数的值,如上图继续扫描到 01 <= 19,则就将R位置的值赋值给L位置 ,结果如下:
在这里插入图片描述
然后继续交替移动L下标,向后移动,如上图L一直向后扫描,09比基准数小,继续后移,17比基准数小,继续后移,这时候L和R重合,则base替换此元素。
在这里插入图片描述
左子序列都比19小,右子序列都比19大
在这里插入图片描述
然后对左右子序列重复以上操作即可。

代码实现

/**
 * @ClassName QuickSort
 * @author: shouanzh
 * @Description 快速排序
 * @date 2022/5/8 17:42
 */
public class QuickSort {

	public static void main(String[] args) {
		int[] array = new int[]{100, 89, 66, 1, -1, 30, 5, 85, -25};

		quickSort(array, 0, array.length - 1);

		System.out.println(Arrays.toString(array)); // [-25, -1, 1, 5, 30, 66, 85, 89, 100]
	}

	/**
	 * 快速排序
	 * @param arr 数组
	 * @param left 数组左边界
	 * @param right 数组右边界
	 */
	private static void quickSort(int[] arr, int left, int right) {

		if (left < right) {
			// 每次分割的点pos
			int pos = partition(arr, left, right);

			// 左子序列 比base小的数字的数组
			quickSort(arr, left, pos - 1);
			// 右子序列 比base大的数字的数组
			quickSort(arr, pos + 1, right);
		}

	}


	private static int partition(int[] arr, int left, int right) {
		// 基准数据
		int base = arr[left];
		while (left < right) {
			// 从后向前找,比base大,right--
			while (left < right && arr[right] >= base) {
				right--;
			}
			// 比base小,替换left所在位置的数字
			arr[left] = arr[right];

			// 从前向后找,比base小,left++
			while (left < right && arr[left] <= base) {
				left++;
			}
			// 比base大,替换right所在位置的数字
			arr[right] = arr[left];

		}
		// 此时left=right,用base替换这个位置的数字
		arr[left] = base;
		return left; // 返回base的正确位置
	}
}

🤯

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值