在java基础的学习过程中,排序方法是一个难点,也是一个重要的知识,需要我们去认真去分析和理解。
JAVA中有十大排序方法,具体方法如下分类,这里主要也必须掌握冒泡排序、快速排序、插入排序、选择排序、归并排序。本文主要为大家讲解快速排序的方法和思路。
,
一、快速排序的思想
这里针对数组元素排序来讲解分割排序的思路,快排简单来说就是通过划分元素索引区间来加快排序速度。这里的元素索引区间值得是元素个数。
1、选择一个基准点:这里选择一个基准点,可以以元素区间的最左边的数为基准点;
2、选定两个指针:这里指针就是元素的索引,为了找到比基准点大或小的数,记录索引进行数值交换。通过这两个指针的初始值是元素区间的两端的值。即区间是[a,b],那么指针初始值就是i=a,j=b;此处选定基准点num=arr[a]
3、右指针从右往左查找小于num的数arr[j],将arr[j]的值赋值为arr[a];(此处arr[a]的值已被覆盖,原先的值也就是基准值,已经保存在num中)
4、左指针从左往右查找大于num的数arr[i],将arr[j]的值赋值给arr[i];
5、依次循环3、4的步骤,知道 i = j 时,说明此时arr[i]左边的值都是小于num的值,arr[j]右边的值都是大于num的值,继而将基准值num赋值给此时的arr[i]。
6. 中间值num已经找到,由num值重新划分区间,[ a , i +1] , [ i-1,b] ,[ a , i +1]区间里面的数都是<num,[ i-1,b]里面的数都是>num;依据3.4.5的步骤对这两个区间进行再次划分,知道区间里面只有一个元素。
二、代码实现过程
第一步:定基准值num=arr[0], 此数组区间为[0,4] | |||||
num=arr[0]=30 | |||||
i=0 | j=4 | ||||
arr | 30 | 50 | 42 | 20 | 45 |
第二步:右指针 j 从右往左找<num的数 | |||||
num=arr[0] | |||||
i=0 | j=3 | ||||
arr | 30 | 50 | 42 | 20 | 45 |
第三步:右指针 j找到arr[3]<num, 则arr[0]=arr[3] | |||||
num=arr[0] | |||||
i=0 | j=3 | ||||
arr | 20 | 50 | 42 | 20 | 45 |
第四步:左指针 i 从左往右找>num的数 | |||||
num=arr[0] | |||||
i=1 | j=3 | ||||
arr | 20 | 50 | 42 | 20 | 45 |
第五步:左指针 i找到arr[1]>num,则arr[3]=arr[1] | |||||
num=arr[0] | |||||
i=1 | j=3 | ||||
arr | 20 | 50 | 42 | 50 | 45 |
第六步:右指针 j 继续从右往左找<num的数,找到j=1时,i=j | |||||
num=arr[0] | j=1 | ||||
i=1 | |||||
arr | 20 | 50 | 42 | 50 | 45 |
第七步:i=j时,停止查找工作,此时arr[1]=num | |||||
num=arr[0] | j=1 | ||||
i=1 | |||||
arr | 20 | 50 | 42 | 50 | 45 |
第八步:此时1为基准值num的索引,以该索引划分区间 [0,0]、[2,4],继续重复以上步骤 | |||||
最终,循环使得排列顺序完成 |
三、代码实现
import java.util.Arrays;
//@Author
//@Date
//@Description
public class Ceshi {
public static void main(String[] args) {
int[] arr = {2, 4, 5, 3, 8, 2, 9};
System.out.println(Arrays.toString(arr));
Quick(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
public static void Quick(int[] arr, int s, int e) {
if (s >= e) { //左索引s=右索引e,就一个元素不需要排序
//左索引s=右索引e,索引输入错误
return; //无参返回
}
int i = s; //定义左索引
int j = e; //定义右索引
int num = arr[s]; //定义基准值
while (i < j) { //循环条件是:当左指针值小于右指针值,
// 表示左指针和右指针重合了,区间内所有值都已经查询完毕,结束循环
while (arr[j] >= num && j > i) { j--; } // 右指针从右向左查找小于基准值num的值
arr[i] = arr[j]; //找到<num的arr[j]值后交换给arr[i],
// 使得大于num的值都在基准值的左边
while (arr[i] <= num && j > i) { i++; } // 左指针从左向右查找大于基准值num的值
arr[j] = arr[i];//找到>num的arr[i]值后交换给arr[j],使得大于num的值都在基准值的右边
} //循环结束,找到基准值的位置arr[i]
arr[i] = num; //将基准值放在其位置
Quick(arr, s, i - 1);
Quick(arr, i + 1, e); //找到基准值的位置,通过基准值划分新的区间[s,i-1],[i+1,e],arr[i]值位置已经确定
// [s,i-1]区间值都小于基准值,[i+1,e]大于基准值,再次调用Quick排序类进行再次排序处理
// 此处用到了递归的方式,
}
}