冒泡排序(Bubble Sort)是一种基础的排序算法,其核心原理是反复比较相邻的元素,若顺序错误就把它们交换过来。下面为你详细介绍 JavaScript 实现冒泡排序的方法:
算法步骤
- 比较相邻元素:依次比较数组中相邻的两个元素,如果顺序错误(如升序排列时前一个元素比后一个大),就交换它们的位置。
- 重复比较:对每一对相邻元素都执行同样的比较和交换操作,从数组的起始位置一直到末尾。每完成一轮这样的操作,数组末尾的元素就会是当前最大(或最小)的元素。
- 减少比较范围:重复上述步骤,但每一轮比较的元素范围会逐渐减少,直到整个数组都被排序好。
JavaScript 实现
function bubbleSort(arr) {
const len = arr.length;
// 控制比较轮数
for (let i = 0; i < len - 1; i++) {
// 标记是否发生交换
let swapped = false;
// 每轮比较的元素范围
for (let j = 0; j < len - 1 - i; j++) {
// 如果前一个元素大于后一个元素,则交换它们
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
swapped = true;
}
}
// 如果没有发生交换,说明数组已经有序,提前结束排序
if (!swapped) break;
}
return arr;
}
// 示例使用
const unsortedArray = [64, 34, 25, 12, 22, 11, 90];
console.log(bubbleSort(unsortedArray)); // 输出: [11, 12, 22, 25, 34, 64, 90]
代码解释
- 外层循环(
i
):控制排序的轮数,总共需要进行n-1
轮,其中n
是数组的长度。 - 内层循环(
j
):每一轮比较相邻的元素,比较范围随着轮数的增加而减少(len - 1 - i
)。 - 交换操作:使用 ES6 的解构赋值语法
[a, b] = [b, a]
来交换两个元素的位置。 - 优化(
swapped
标志):如果某一轮比较中没有发生交换,说明数组已经有序,此时可以提前结束排序,从而提高效率。
复杂度分析
- 时间复杂度:在最坏和平均情况下为 O(n²),最好情况下(数组已经有序)为 O(n)(由于添加了
swapped
标志)。 - 空间复杂度:O(1),因为只需要常数级的额外空间。
冒泡排序的特点
- 优点:实现简单,适合小规模数据排序。
- 缺点:时间复杂度较高,对于大规模数据排序效率较低。
优化版本(可选)
如果需要处理几乎有序的数据,可以进一步优化冒泡排序,记录最后一次交换的位置,从而减少后续比较的范围:
function optimizedBubbleSort(arr) {
let len = arr.length;
while (len > 0) {
let lastSwappedIndex = 0;
for (let i = 0; i < len - 1; i++) {
if (arr[i] > arr[i + 1]) {
[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]];
lastSwappedIndex = i + 1;
}
}
len = lastSwappedIndex; // 下一轮只需比较到最后一次交换的位置
}
return arr;
}
冒泡排序虽然不是最高效的排序算法,但它的原理简单易懂,常被用作学习排序算法的入门示例。在实际应用中,对于大规模数据,建议使用快速排序、归并排序等效率更高的算法。