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

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

相关推荐
深圳市快瞳科技有限公司20 小时前
宠物生物特征识别:鼻纹、面部与多模态融合技术的突破
人工智能·算法·计算机视觉·宠物
格兰芬多呼神护卫20 小时前
# Agent 企业评估方案深度分析:从“看答案”到持续质量闭环_码士教育
java·开发语言·jvm
番茄炒鸡蛋加糖21 小时前
Spring 事务传播机制 & 事务失效场景
java·后端·spring
这就是佬们吗21 小时前
回溯算法三板斧---掌握「回溯三问」思考模板快速入门回溯
java·数据库·算法
qq_1715388521 小时前
深入浅出 MyBatis XML:从入门到精通
xml·java·mybatis
冻柠檬飞冰走茶21 小时前
PTA基础编程题目集 7-24 约分最简分式(C语言实现)
c语言·开发语言·数据结构·算法
zander25821 小时前
LeetCode 78. 子集
算法·leetcode·深度优先
qq_1715388521 小时前
Spring TransactionSynchronizationManager:事务同步的幕后指挥官
java·后端·spring
要开心吖ZSH21 小时前
一次 HikariCP 连接池耗尽导致的线上雪崩排查实录——完整排查报告
java·spring boot·mysql·连接池·hikaricp