十大排序算法之二 - 快速排序
1.快速排序的介绍
- 同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的
- 不同的是,冒泡排序在每一轮中只把1个元素冒泡到数列的一端,而快速排序则在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成两个部分,这种思路就叫作分治法
- 基准元素的选择
- 基准元素,英文是pivot,在分治过程中,以基准元素为中心,把其他元素移动到它的左右两边,我们可以随机选择一个元素作为基准元素,并且让基准元素和数列首元素交换位置
2. 双边排序法(双指针)
2.1 实现图解
2.2 Java代码实现
package com.lagou.quickSort;
/**
* @author 云梦归遥
* @date 2022/5/16 18:45
* @description 快速排序法 - 双边排序法
*/
public class QuickSortByDoubleMethod {
public int[] quickSort(int[] array){
if (array == null) return null;
// 双边循环法
doubleSideSort(array, 0, array.length - 1);
return array;
}
// 双边循环法
private void doubleSideSort(int[] array, int leftIndex, int rightIndex){
if (array == null || rightIndex <= leftIndex) return;
int flag = leftIndex;
int newLeftIndex = leftIndex;
int newRightIndex = rightIndex;
while (true){
// 右指针判断
while (leftIndex < rightIndex && array[rightIndex] >= array[flag]){
rightIndex--;
}
// 左指针判断
while (leftIndex < rightIndex && array[leftIndex] <= array[flag]){
leftIndex++;
}
// 交换左右指针的数据
if (leftIndex < rightIndex){
int temp = array[rightIndex];
array[rightIndex] = array[leftIndex];
array[leftIndex] = temp;
}
// 左右指针相遇,与 flag 交换数据
if (leftIndex == rightIndex){
// 交换值
int temp = array[leftIndex];
array[leftIndex] = array[flag];
array[flag] = temp;
flag = leftIndex;
break;
}
}
// 递归判断
// 对 flag 左边的数组进行 双边循环
doubleSideSort(array, newLeftIndex, flag - 1);
// 对 flag 右边的数组进行 双边循环
doubleSideSort(array, flag + 1, newRightIndex);
}
}
进行测试
package com.lagou.quickSort.test;
import com.lagou.quickSort.QuickSortByDoubleMethod;
import java.util.Arrays;
/**
* @author 云梦归遥
* @date 2022/5/16 19:11
* @description
*/
public class QuickSortByDoubleTest {
public static void main(String[] args) {
QuickSortByDoubleMethod quickSortMethod = new QuickSortByDoubleMethod();
int[] array = {3, 5, 2, 4, 6, 1, 7, 9, 8};
int[] sort = quickSortMethod.quickSort(array);
System.out.println("【快速排序 - 双边循环】" + Arrays.toString(sort));
}
}
3.单边循环法(单指针)
3.1 实现图解
3.2 Java实现
package com.lagou.quickSort;
/**
* @author 云梦归遥
* @date 2022/5/16 20:39
* @description 快速排序法 - 单边排序法
*/
public class QuickSortBySingleMethod {
public int[] quickSort(int[] array){
if (array == null) return null;
// 调用单边排序法来进行处理
singleSort(array, 0, array.length - 1);
return array;
}
private void singleSort(int[] array, int leftIndex, int rightIndex){
if (array == null || leftIndex >= rightIndex) return;
int flag = leftIndex;
int move = flag; // 记录小于 flag 范围的数
int newLeftIndex = leftIndex;
int newRightIndex = rightIndex;
// 循环判断
int temp = 0;
for (int i = leftIndex; i <= rightIndex; i++){
if (array[flag] > array[i]){
move++;
temp = array[i];
array[i] = array[move];
array[move] = temp;
}
}
// 交换 flag 与 move
temp = array[move];
array[move] = array[flag];
array[flag] = temp;
// 进行迭代,处理 move 两边的数组
singleSort(array, newLeftIndex, move - 1);
singleSort(array, move + 1, newRightIndex);
}
}
进行测试
package com.lagou.quickSort.test;
import com.lagou.quickSort.QuickSortBySingleMethod;
import java.util.Arrays;
/**
* @author 云梦归遥
* @date 2022/5/16 20:53
* @description
*/
public class QuickSortBySingleTest {
public static void main(String[] args) {
QuickSortBySingleMethod quickSortBySingleMethod = new QuickSortBySingleMethod();
int[] array = {3, 5, 2, 4, 6, 1, 7, 9, 8};
int[] sort = quickSortBySingleMethod.quickSort(array);
System.out.println("【快速排序 - 单边循环】" + Arrays.toString(sort));
}
}
4.总结
- 快速排序时间复杂度为:O(nlogn)