写代码时,排序是最常见的操作之一。刚学算法的人常被冒泡排序和选择排序搞晕,看起来都是把一堆数字从小到大排好,但其实它们干活的方式差得挺远。
冒泡排序:像水里的气泡慢慢上浮
冒泡排序的核心是“相邻比较,交换位置”。它一遍一遍地扫描数组,每次把最大的那个数“推”到末尾,就像水底的气泡一个个浮上来一样。
比如你手里有一串乱序的数字:5, 3, 8, 1。第一轮从头开始比,5 和 3 换,5 和 8 不换,8 和 1 换……最后 8 跑到最后。第二轮继续,7 次比较后,7 又归位。就这样一轮轮扫,直到全部有序。
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
选择排序:每次都挑最小的那个
选择排序不怎么“交换”,它更像一个精打细算的人。每一轮,它在未排序的部分里找出最小值,直接把它和当前位置交换。不管中间隔了多少数,只关心“谁最小”。
还是那串数字:5, 3, 8, 1。第一轮找最小,发现是 1,就让 1 和第一个位置的 5 换。第二轮在剩下三个里找最小,是 3,已经在正确位置了,不动。接着是 5 和 8,依次搞定。
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
if (minIndex != i) {
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
关键区别在哪?
冒泡排序在每一轮中频繁交换,只要前面比后面大就换,整个过程交换次数多,但逻辑简单,适合教学。而选择排序每轮只交换一次,效率稍高一点,尤其是数据量稍大时,节省了不少操作。
举个生活例子:冒泡排序像一群人在排队,每次只能和旁边的人调位置,一点点挪到该站的地方;选择排序则像老师点名,每次直接把最矮的同学拉出来站到队首,干脆利落。
时间复杂度上,两者都是 O(n²),在实际开发中都不算快,但理解它们有助于掌握更复杂的排序逻辑。面试时也常被拿来考,因为能看出你是不是真懂循环和交换的本质。