2.5 快速排序(Quick sort)
本文最后更新于 2024-07-06,文章内容可能已经过时。
2.5 快速排序(Quick sort)
一. 定义
快速排序(Quick sort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
具体流程
首先设定一个分界值,通过该分界值将数组分成左右两部分。
将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
概括来说为 挖坑填数 + 分治法。
参考自:https://blog.csdn.net/justidle/article/details/104203963
二. 代码实现
方法一:以第一个元素为枢轴
/**
* desc 快速排序
* @author GreyPigeon mail:2371849349@qq.com
* @since 2024-01-12-21:56
**/
public class QuickSort {
public static void main(String[] args) {
int[] arry = {9,2,7,6,5,8,3,2,1};
quickSort(arry,0, arry.length-1);
System.out.println(Arrays.toString(arry));
}
public static void quickSort(int[] arry,int left,int right){
//运行判断,如果左边索引大于右边是不合法的,直接return结束次方法
if(left>right){
return;
}
//定义变量保存基准数(枢轴)
int pivot = arry[left];
//定义变量i,指向最左边
int i = left;
//定义j ,指向最右边
int j = right;
//当i和j不相遇的时候,再循环中进行检索
while(i!=j){
//先由j从右往左检索比基准数小的,如果检索到比基准数小的就停下。
//如果检索到比基准数大的或者相等的就停下
while(arry[j]>= pivot && i<j){
j--; //j从右往左检索
}
while(arry[i]<= pivot && i<j){
i++; //i从左往右检索
}
//代码走到这里i停下,j也停下,然后交换i和j位置的元素
int temp = arry[i];
arry[i] = arry[j];
arry[j] = temp;
}
//如果上面while条件不成立,就说明 i和j相遇了,就交换基准数这个元素和相遇位置的元素
arry[left] = arry[i];
//把基准数赋给相遇位置的元素
arry[i] = pivot;
//基准数在这里递归就为了左边的数比它小,右边的数比它大
//排序基准数的左边
quickSort(arry,left,i-1);
//排序基准数的左边
quickSort(arry,j+1,right);
}
}
方法二:以中间元素为枢轴
/**
* desc 快速排序
* @author GreyPigeon mail:2371849349@qq.com
* @since 2024-01-12-21:56
**/
public class QuickSort {
public static void main(String[] args) {
int[] arr = {-9,78,0,23,-567,70, -1,900, 4561};
quickSort(arr, 0, arr.length-1);
System.out.println("arr=" + Arrays.toString(arr));
}
public static void quickSort(int[] arr,int left, int right) {
int l = left; //左下标
int r = right; //右下标
//pivot 中轴值
int pivot = arr[(left + right) / 2];
int temp = 0; //临时变量,作为交换时使用
//while循环的目的是让比pivot 值小放到左边
//比pivot 值大放到右边
while( l < r) {
//在pivot的左边一直找,找到大于等于pivot值,才退出
while( arr[l] < pivot) {
l += 1;
}
//在pivot的右边一直找,找到小于等于pivot值,才退出
while(arr[r] > pivot) {
r -= 1;
}
//如果l >= r说明pivot 的左右两的值,已经按照左边全部是
//小于等于pivot值,右边全部是大于等于pivot值
if( l >= r) {
break;
}
//交换
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
if(arr[l] == pivot) {
r -= 1;
}
//如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
if(arr[r] == pivot) {
l += 1;
}
}
// 如果 l == r, 必须l++, r--, 否则为出现栈溢出
if (l == r) {
l += 1;
r -= 1;
}
//向左递归
if(left < r) {
quickSort(arr, left, r);
}
//向右递归
if(right > l) {
quickSort(arr, l, right);
}
}
}
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员Graypigeon
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果