🟡前言
21天挑战赛第二周。本文主要讲述有关快速排序的内容
活动地址:CSDN21天学习挑战赛
🟡概述
1️⃣原理图
2️⃣排序原理
1.首先设定一个分界值 ,通过该分界值将数组分成左右两部分
2.将大于或等于分界值的数据放到到数组右边,小于分界值的数据放到数组的左边
此时左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值
3.左边和右边的数据可以独立排序;
对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理
4.重复上述过程,当左侧和右侧两个部分的数据排完序后,整个数组的排序也就完成了
🟡拆分及分治思想
1️⃣拆分的解题思路
1.找一个基准值(一般是数组第一个元素),并用两个“指针”指向数组的头部和尾部
2.从右向左(从尾到头) 搜索一个比基准值小的元素,当找到时停止搜索并记录指针位置
3.再从左到右(从头到尾)搜索一个比基准值大的元素,当找到时停止搜索并记录指针位置
4.交换左右指针的位置
5.重复上述步骤,直至左右指针指向同一个元素
2️⃣拆分中分治思想体现
3️⃣拆分的代码实现
public static int partition(Comparable[]a, int lo, int hi){ //确定分界值 Comparable key = a[0]; //定义两个指针 int left = lo; int right = hi + 1; //拆分数组 while (true){ //从右往左移动指针,当遇到元素值比key小就停止 while (less(key, a[--right])){ if(right == lo){ break; } } //从左往右移动指针,当遇到元素值比key大就停止 while (less(a[++left], key)){ if (left == hi) { break; } } //当指针指向同一元素时结束循环 if(left >= right){ break; } //当左边的元素值更大时,交换两者位置 else { exch(a,left,right); } } //当完成拆分后,交换当前分界值的指针与首个元素对应的指针 exch(a, lo, right); return right; }
🟡调用API实现快速排序
1️⃣构造方法和成员方法
构造方法
Quick();
成员方法
- public static void sort(Comparable[]a):对数组a中元素进行排序
- public static boolean less(Comparable x, Comparable y):判断x是否小于y
- public static void exch(Comparable[]a, int i, int j):交换数组a中下标为 i 和 j 的元素
- public static int partition(Comparable[]a, int lo, int hi):对数组a中索引从lo到hi之间元素分组,返回分组界限对应索引
- public static void sort(Comparable[]a, int lo, int hi):对数组a中从索引lo到索引hi之间元素进行排序
2️⃣解题思路
1.定义less方法用来比较元素大小
2.定义exch方法用来交换数组内元素
3.定义一个sort方法来对数组内元素排序
4.定义一个partition方法来对数组进行拆分排序
5.定义一个sort的重载方法,并在方法内调用sort方法对子组排序(递归)
3️⃣完整代码
public class QuickSort { private static void exch(Comparable[] a, int i, int j){ Comparable temp; temp = a[i]; a[i] = a[j]; a[j] = temp; } public static boolean less(Comparable x, Comparable y){ return x.compareTo(y) < 0; } public static void sort(Comparable[] a){ int lo = 0; int hi = a.length-1; sort(a,lo,hi); } public static void sort(Comparable[]a, int lo, int hi){ //安全性校验 if(hi <= lo){ return; } //调用方法对数组进行分组 int partition = partition(a, lo, hi); //对左子数组排序 sort(a,lo,partition-1); //对右子数组排序 sort(a,partition+1,hi); } public static int partition(Comparable[]a, int lo, int hi){ //确定分界值 Comparable key = a[0]; //定义两个指针 int left = lo; int right = hi + 1; //拆分数组 while (true){ //从右往左移动指针,当遇到元素值比key小就停止 while (less(key, a[--right])){ if(right == lo){ break; } } //从左往右移动指针,当遇到元素值比key大就停止 while (less(a[++left], key)){ if (left == hi) { break; } } if(left >= right){ break; } //当左边的元素值更大时,交换两者位置 else { exch(a,left,right); } } //当完成拆分后,交换分界值 exch(a, lo, right); return right; } }
🟡结语
快速排序利用了递归和分治思想来实现,至此所有的排序都已经讲解完毕,接下来是有关链表的知识