冒泡、快排、堆排的实现逻辑与选择思路

冒泡排序是最直观的排序方法。从头开始两两比较相邻元素,前面比后面大就交换,一趟下来最大的元素沉到了最后。重复n-1趟就排完了。加一个swapped标志可以提前结束,某一趟没有发生交换就说明已经有序了。

复制代码
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
boolean swapped = false;
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
if (!swapped) break;
}
}

冒泡排序是稳定的,相等的元素不会交换。时间复杂度O(n²),适合数据量小的场景。

快速排序是分治思想的典型应用。每次选一个基准值,通过一趟扫描把比基准小的放左边,比基准大的放右边,基准就放到了它最终的位置上。然后递归处理左右两部分。

分区的过程:用i和j两个指针,j从左到右扫描,遇到比基准小的就和i位置交换,i后移。扫描完后i左边的都比基准小,i右边都比基准大,最后把基准放到i的位置。

复制代码
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}

private static int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] <= pivot) {
i++;
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;
}

快速排序平均O(n log n),但极端情况下会退化成O(n²),比如数组已经有序且基准总选最后一个。实际工程里会对基准选择做优化,比如三数取中。

堆排序利用了大顶堆的性质:父节点永远比子节点大。第一步把无序数组构建成大顶堆,从最后一个非叶子节点开始依次下沉。第二步反复把堆顶和末尾交换,然后调整剩余元素重新成堆。

建堆的复杂度是O(n),每次调整是O(log n),总复杂度O(n log n)。堆排序不稳定,因为跳跃式交换会打乱相等元素的相对顺序。

复制代码
public static void heapSort(int[] arr) {
int n = arr.length;
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
for (int i = n - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}

private static void heapify(int[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest]) largest = left;
if (right < n && arr[right] > arr[largest]) largest = right;
if (largest != i) {
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
heapify(arr, n, largest);
}
}

三种排序怎么选:数据量小、要求稳定用冒泡。数据量大、随机性强用快排,它常数小,实际跑起来最快。不想让快排出现最坏情况,或者对空间有要求,堆排序更稳健。归并排序虽然也是O(n log n)且稳定,但要额外开空间,这里没展开。

相关推荐
坚定信念,勇往无前几秒前
Maven 私有仓库-nexus
java
大熊背2 分钟前
树莓派相机自动白平衡详解(四)
算法·树莓派·白平衡·isppipeline
一米阳光86615 分钟前
软考(中级)软件设计师核心笔记(9)算法——背包问题
笔记·算法·职场发展·软考·软件设计师·中级职称
Minner-Scrapy8 分钟前
Scrapy 2.17 源码解析:Scheduler 调度器与磁盘/内存双队列
java·爬虫·python·scrapy·网络爬虫·twisted
晚风醉蝶17 分钟前
1-11-奇偶排序-OddEvenSort
java·数据结构·算法
旖旎夜光23 分钟前
LeetCode 852:山脉数组的峰顶索引(二分查找) —— 题解
数据结构·c++·算法·leetcode·二分查找
夏天拐跑了西瓜41 分钟前
Spring Cloud 微服务实战(三):一个服务挂了,凭什么拖垮整个系统?Sentinel 限流熔断实战
java·spring cloud·微服务
2601_967264281 小时前
Jetpack Compose 实践指南:从入门到进阶
java·学习
m0_587383002 小时前
社区家政系统开发实战:从需求分析到上线部署全指南
java·spring boot·spring·需求分析
凤山老林2 小时前
动态 i18n 体系落地:Spring Boot 多租户热加载与前后端协同实践
java·spring boot·后端·i18n