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

冒泡排序是最直观的排序方法。从头开始两两比较相邻元素,前面比后面大就交换,一趟下来最大的元素沉到了最后。重复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)且稳定,但要额外开空间,这里没展开。

相关推荐
无限码力4 分钟前
小红书笔试真题 9.17 - 待发热度重排(C++/Py/Java /Js/Go)
java·小红书·小红书笔试真题·小红书技术岗笔试真题
卓怡学长10 分钟前
w194基于ssm新能源汽车充电系统小程序
java·小程序·intellij-idea
坤坤子吖17 分钟前
算法学习——高精度加减乘除
c++·笔记·学习·算法
JAVA面经实录91718 分钟前
Java高级后端 · 全套面试通关手册(MySQL)
java·mysql·面试
CQU_JIAKE25 分钟前
10.1[A]2267,磐久UMX【上下文128K,KVCache部分]
算法
朝朝辞暮i30 分钟前
C++ 第 14 课:引用 &
开发语言·c++·算法
光依旧32 分钟前
MCP实战手记(八):从“能跑“到“能上线“——无状态MCP Server的生产落地清单
java·人工智能·spring boot·架构·ai agent·mcp
Joe_Wang51 小时前
【从0到1学习JVM · 21】既不浪费空间又没有碎片,标记整理算法到底慢在哪
jvm·学习·算法·垃圾回收·标记整理算法
让学习成为一种生活方式1 小时前
PlantCellChat--单细胞与空间转录组数据预测植物细胞间通讯的R包--The Plant Journal
算法
C++ 老炮儿的技术栈1 小时前
有符号变量与无符号变量的区别
服务器·开发语言·前端·数据结构·c++·算法·c