网站首页 > java教程 正文
快速排序(Quick Sort)是一种常用的排序算法,它的时间复杂度为O(nlogn),是在平均情况下具有良好性能的排序算法之一。
一、原理
快速排序算法采用了分治的思想,将一个大问题分解成若干个小问题来解决。其基本思路是选取一个基准元素,将数组分成两个子序列,其中一个子序列的所有元素都小于基准元素,另一个子序列的所有元素都大于或等于基准元素。然后再对这两个子序列进行递归操作,直到所有序列长度为1时排序完成。
快速排序的平均时间复杂度为O(nlogn),最坏情况下的时间复杂度为O(n^2),其中n为待排序的元素个数。快速排序对于大规模数据的排序效率比较高,是常用排序算法之一。
二、快速排序算法实现过程
快速排序的实现需要完成以下几步:
- 选择序列中的一个元素作为基准值(pivot),通常选择首个元素或末尾元素作为基准值;
- 将低于基准元素的放到左边,高于或等于基准元素的放到右边。
- 对基准值左右两侧的子序列分别重复上述步骤,直到所有元素均被排完序为止。
2.1 选择基准元素
选择基准元素是快速排序的第一步,其目的是将待排序数组分成两个子序列。最常用的方法是选取第一个元素作为基准元素。但是,如果待排序数组已经有序或近乎有序,那么选取第一个元素就会导致快速排序的时间复杂度变为O(n^2)。为了解决这个问题,可以采用随机化的方法来选择基准元素。
以下是选取第一个元素作为基准元素的代码实现:
public static int partition(int[] arr, int low, int high) {
int pivot = arr[low]; //基准元素
while (low < high) {
while (low < high && arr[high] >= pivot) {
high--;
}
arr[low] = arr[high]; //将比基准元素小的移到低端
while (low < high && arr[low] <= pivot) {
low++;
}
arr[high] = arr[low]; //将比基准元素大的移到高端
}
arr[low] = pivot; //把基准元素放到最终位置
return low;
}
以下是采用随机化方法选择基准元素的代码实现:
public static int partition(int[] arr, int low, int high) {
int randomIndex = (int) (Math.random() * (high - low + 1)) + low; //随机选取一个位置
swap(arr, randomIndex, high); //交换基准元素和随机元素
int pivot = arr[high]; //基准元素
while (low < high) {
while (low < high && arr[low] <= pivot) {
low++;
}
arr[high] = arr[low]; //将比基准元素大的移到高端
while (low < high && arr[high] >= pivot) {
high--;
}
arr[low] = arr[high]; //将比基准元素小的移到低端
}
arr[high] = pivot; //把基准元素放到最终位置
return high;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
2.2 将低于基准元素的放到左边,高于或等于基准元素的放到右边
这一步是快速排序的关键步骤,其代码实现如下:
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pivotIndex = partition(arr, low, high);
quickSort(arr, low, pivotIndex - 1); //递归排序左半部分
quickSort(arr, pivotIndex + 1, high); //递归排序右半部分
}
}
2.3 对基准值左右两侧的子序列分别重复上述步骤,直到所有元素均被排完序为止。
这一步是快速排序的递归过程,其代码实现如上文所示。
三、示例代码
下面是使用Java语言实现快速排序的示例代码:
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] arr = {32, 6, 17, 28, 10, 22, 43, 13, 48, 35};
System.out.println("Before sorting: " + Arrays.toString(arr));
quickSort(arr, 0, arr.length - 1);
System.out.println("After sorting: " + Arrays.toString(arr));
}
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pivotIndex = partition(arr, low, high);
quickSort(arr, low, pivotIndex - 1); //递归排序左半部分
quickSort(arr, pivotIndex + 1, high); //递归排序右半部分
}
}
public static int partition(int[] arr, int low, int high) {
int randomIndex = (int) (Math.random() * (high - low + 1)) + low; //随机选取一个位置
swap(arr, randomIndex, high); //交换基准元素和随机元素
int pivot = arr[high]; //基准元素
while (low < high) {
while (low < high && arr[low] <= pivot) {
low++;
}
arr[high] = arr[low]; //将比基准元素大的移到高端
while (low < high && arr[high] >= pivot) {
high--;
}
arr[low] = arr[high]; //将比基准元素小的移到低端
}
arr[high] = pivot; //把基准元素放到最终位置
return high;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
四、动图效果演示
上面的动图效果的步骤,首先基准值取第一个元素32,然后逐一比较,把小于基准值的移到左侧,大于基准值的移到右侧。整个数组拆分成了P1、P2两个数组
接着对左侧的P1数组进行快速排序,基准值取第一个元素13,那么P1数组又被拆分成更小的左右两个数组P3、P4。
继续对上面拆分出来的P3数组快速排序,基准值取第一个元素10
左侧数组的长度已经是1,排序已经完成,开始对13的右边P4数组快速排序,基准值取第一个元素28,P4中没有比基准值28大的数字,所以只有左侧的P5数组
接着是28的左侧P5数组快速排序,基准值取第一个元素22,
结果数组长度已经是1,结束。
接着对32的右侧部分P2数组快速排序,基准值取第一个元素43
到这里,所有最小单位的数组都已经拆成了长度为1的数组,无法继续拆分,快速排序结束得到了最终的结果。
猜你喜欢
- 2024-10-09 一遍记住 8 种排序算法与 Java 代码实现
- 2024-10-09 java程序员必知的八大排序(java编程排序算法实现)
- 2024-10-09 Java实现堆排序(java堆排序算法代码)
- 2024-10-09 插入排序算法,就这么简单,还学不会算我输
- 2024-10-09 程序员必知的十大基础实用算法之-快速排序算法
- 2024-10-09 【数据结构与算法】十大经典排序算法-快速排序
- 2024-10-09 经常用到的的排序(快速排序和归并排序)简单的计算机算法学习
- 2024-10-09 排序算法——快排(快速排序算法实例讲解)
- 2024-10-09 七种基于比较的排序,基于Java实现,收藏一下?
- 2024-10-09 十大经典排序算法动画与解析,看我就够了!(配代码完全版)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)