目录
代码实现(java):
一、首元素作为基准值
图:
编辑
基本思路:
代码:
代码补充说明:
二、中间元素作为基准值
代码:
参考学习文章:
今天我们不刷力扣了,我们来复习(手撕)一下数据结构中的八大排序算法之一,快速排序
基本概念:
快速排序使用分治法策略来把一个串行分为两个子串行。
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法
注 : 分治法:Divide and conquer,行: list,子串行: sub-lists
冒泡排序:冒泡排序,详详解解-CSDN博客
上图:
算法步骤:
1、首先在数组中挑选一个元素作为基准值
2、将数组中大于基准值的元素,移到基准值右边
3、将数组中小于基准值的元素,移到基准值左边
4、对基准值左右 两侧的子序列重复上述操作(以递归方式)
注 :
1、基准值:pivot 递归:recursive
2、基准值选择,第一个元素或者中间元素
代码实现(java):
main函数
public class QuickSort {
public static void main(String[] args) {
int[] arr = {3, 45, 78, 99, 45, 11, 64, 55, 52, 11, 18, 66, 17, 37, 199, 120, 54, 49};
System.out.println("未排序的数组:" + Arrays.toString(arr));
quickSort01(arr, 0, arr.length - 1);
System.out.println("排序的数组:" + Arrays.toString(arr));
}
注意: 传过去的参数 是数组首和尾元素
一、首元素作为基准值
图:
基本思路:
首先将left与right指针 赋值给 临时指针le和ri
while循环( le和ri指针相遇时跳出循环)
·循环右指针ri左移,遇到小于或等于基准值元素 停止移动
·循环右指针le右移,遇到大于或等于基准值元素 停止移动
· if 判断
若le与ri相遇即指向同一元素,则将该元素与与数组第一个元素互换
否则将le与ri所指向元素互换位置
最后递归对对基准值左右两边数进行排序
代码:
/**
* 快速排序算法(以第一个元素为基准)
* @param arr 排序的数组
* @param left 数组的第一个元素索引
* @param right 数组的最后一个元素索引
*/
private static void quickSort01(int[] arr,int left,int right){
if (left >= right) return;//递归退出条件
int le = left;//le为数组的左指针
int ri = right;//ri为数组的右指针
while (le<ri){
//若右指针所指元素 大于或等于 基准数,右指针左移
while (arr[ri]>=arr[left] && le<ri) ri--;
//若左指针所指元素 小于或等于 基准数,左指针右移
while (arr[le]<=arr[left] && le<ri ) le++;
if (le == ri){/若两个指针指向同一元素,将此元素 与第一个元素 对调位置
int tmp = arr[left];
arr[left] = arr[ri];
arr[ri] = tmp;
}else{//若两个指针没有指向同一个位置,将两个指针 所指向的元素 对调位置
int tmp = arr[le];
arr[le] = arr[ri];
arr[ri] = tmp;
}
}
quickSort02(arr,left,le-1);//递归方式对基数左边的数进行排序
quickSort02(arr,ri+1,right);//递归方式对基数右边的数进行排序
}
}
代码补充说明:
1、当le与ri指针相遇时,基准值被移动到中间了,或说 le与ri指针指向中间
此时,left --- le-1为基准值 左边子序列 ,同理 ri+1 --- right为基准值 右边子序列
2、三个循环都有条件,当le和ri指针相遇时跳出循环
二、中间元素作为基准值
代码:
/**
* 快速排序算法(以中间元素为基准)
* @param arr 排序的数组
* @param left 左指针
* @param right 右指针
*/
private static void quickSort01(int[] arr,int left,int right){
int l = left;
int r = right;
int pi = arr[(left+right)/2];//选取数组中间元素作为基准
int tmp = 0;//tmp作为中间转换变量
while (l<r) {
while (arr[l] < pivot) {//当左元素小于基准时,就往右进一位
l++;
}
while (arr[r] > pivot) {//当右元素大于基准时,就往左进一位
r--;
}
if (l >= r) {//当两个指针指向同一个位置时,就跳出循环
break;
}
//交换值,左指针所指大于基准值的与右指针所指小于基准值的交换位置
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
if (arr[l] == pivot) {//如果左指针指向元素的值等于基准值,右指针往左移动一格
r--;
}
if (arr[r] == pivot) {//如果右指针指向元素的值等于基准值,左指针往右移动一格
l++;
}
}
//第一次排序结束后,用递归的方式,
//开始对基准值两边的元素开始排序
if (l==r){
l++;
r--;
}
if (left<r){
quickSort01(arr,left,r);
}
if (l<right){
quickSort01(arr,l,right);
}
}
结果:
参考学习文章:
1.6 快速排序 | 菜鸟教程 (runoob.com)
排序——快速排序(Quick sort)-CSDN博客
快速排序算法_快速排序所选pivot序列-CSDN博客
重温经典排序算法之快速排序——图解+C/C++实现_c++快速排序算法解析-CSDN博客