快速排序简介
快速排序(Quick Sort)是一种基于分治思想的高效排序算法。它通过选择一个“基准”元素(pivot),将数组分为两部分:一部分包含比基准小的元素,另一部分包含比基准大的元素,然后对这两部分递归排序,最终合并得到有序数组。
易于记忆的方法:
1. 选基准:从数组中选取一个元素作为“基准”。
2. 分区:将数组中的元素按照基准分为两部分:小于基准的放左边,大于基准的放右边。
3. 递归排序:对左、右两部分重复上述步骤,直到每部分只有一个元素。
4. 合并:无需额外步骤,数组通过分区过程已经排好序。
可视化示例:
对数组 [7, 3, 9, 4, 1] 进行快速排序:
1. 选择 7 作为基准。
- 分区:左 [3, 4, 1],基准 [7],右 [9]。
2. 对左 [3, 4, 1] 递归:
- 选择 3 作为基准,分区后为左 [1],基准 [3],右 [4]。
3. 对右 [9] 不需要递归(只有一个元素)。
4. 合并为 [1, 3, 4, 7, 9]。
时间复杂度和空间复杂度
时间复杂度
- 最坏情况:每次分区都选到数组的最大或最小值(如已排序数组),导致分区非常不均匀。
- 比较次数:((n-1), (n-2), \dots, 1),总计 (\frac{n(n-1)}{2})。
- 时间复杂度为 O(n²)。
- 最好情况:每次分区都将数组均分(左右子数组大小相等)。
- 比较次数:(\log_2(n)) 层,每层需要 (n) 次比较。
- 时间复杂度为 O(n \log n)。
- 平均情况:基准选择均匀,效率接近最好情况。
- 平均时间复杂度为 O(n \log n)。
空间复杂度
快速排序是原地排序,但使用了递归调用:
- 最坏情况:递归深度为 (O(n))。
- 最好情况:递归深度为 (O(\log n))。
- 空间复杂度:平均为 O(\log n)。
快速排序在Android开发中的应用
快速排序性能优异,适合处理大量数据,特别是需要频繁排序的大型列表。以下是一些常见应用场景:
-
列表数据排序
- 在 Android 的 RecyclerView 或 ListView 中,快速排序可以用来高效地对数据源进行排序,提升用户界面更新速度。
-
搜索优化
- 在需要快速查找的场景下(如二分查找),快速排序可先将数据排序,提高后续操作效率。
-
大规模数据排序
- 快速排序非常适合处理用户数据或应用中的大规模数据(如电商应用中的商品价格排序)。
-
图形处理
- 在图形相关的操作中,如对多边形的顶点按照某个坐标轴排序(如 X 坐标),快速排序是常见的选择。
示例代码:Android中实现快速排序
以下是在Android项目中实现快速排序的示例代码:
public class QuickSortUtil {
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int partitionIndex = partition(arr, low, high); // 分区
quickSort(arr, low, partitionIndex - 1); // 排序左侧
quickSort(arr, partitionIndex + 1, high); // 排序右侧
}
}
private static int partition(int[] arr, int low, int high) {
int pivot = arr[high]; // 选择最后一个元素为基准
int i = low - 1; // i 指向“比基准小的部分”的最后一个元素
for (int j = low; j < high; j++) {
if (arr[j] < pivot) { // 比基准小的元素交换到左侧
i++; // i 前进一位,准备放置当前元素
// 交换 arr[i] 和 arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 将基准放到正确位置
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1; // 返回基准位置
}
}
详细步骤
1. 选择基准值
基准值用于将数组分为两部分:
int pivot = arr[high];
在此例中,基准值为 arr[high](子数组的最后一个元素)。
2. 初始化指针
我们定义两个指针:
1. i 指向“比基准小的部分”的最后一个元素,初始化为 low - 1。
int i = low - 1;
初始值为 low - 1 是因为还没有任何元素被归类为“小于基准”。
j遍历数组,用于检查每个元素是否需要放到基准的左边。
3. 遍历数组并比较元素
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
// 交换 arr[i] 和 arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
- 遍历范围是
[low...high-1],逐一检查每个元素是否小于基准。 - 如果
arr[j] < pivot,表示arr[j]应归类为“小于基准”,我们执行以下操作:i++,将i向右移动一位。- 交换
arr[i]和arr[j],将当前元素放到“比基准小的部分”。
4. 放置基准元素
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
- 遍历结束后,
i + 1是基准元素应该放置的位置。 - 将
pivot和arr[i + 1]交换,把基准放到正确的位置。
5. 返回分区索引
return i + 1;
- 返回
i + 1作为基准元素的最终位置索引。
使用示例:对 RecyclerView 数据排序
假设一个商品列表需要按价格从低到高排序:
Button sortButton = findViewById(R.id.sortButton);
int[] prices = {300, 150, 200, 100, 250};
sortButton.setOnClickListener(view -> {
QuickSortUtil.quickSort(prices, 0, prices.length - 1);
System.out.println(Arrays.toString(prices)); // 输出有序价格数组
// 更新 RecyclerView 的 Adapter 数据源
recyclerViewAdapter.updateData(prices);
});
总结
快速排序是 Android 开发中处理大规模数据排序的理想选择。其高效的平均性能((O(n \log n)))和灵活的实现方式使其适用于多种场景,如列表排序、搜索优化和图形处理。通过对分治思想的理解,快速排序为实现更复杂的算法奠定了基础。
当前文章价值7.05元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

评论已关闭!