冒泡排序
对于要排序的数组,从第一位开始从前往后比较相邻两个数字,若前者大,则交换两数字位置,然后比较位向右移动一位。第 arr.length - 1 轮结束后排序完成。
从第一个元素开始,重复比较相邻的两个项,若第一项比第二项更大,则交换两者的位置;反之不动。每一轮操作,会将这一轮中最大的元素放置到数组末尾。
看图,更容易理解(未应用优化)。 (本图来自https://leetcode.cn/circle/discuss/eBo9UB/)
1)优化
提前结束优化
当某一轮比较均未发生交换,说明排序已完成,可设置一个布尔值记录一轮排序是否有发生交换,若无则提前退出循环结束程序。
冒泡界优化
记录前一轮交换的最终位置,说明该位置之后的元素为已排序状态,下一轮的交换只需执行到该处。
2)复杂度分析
时间复杂度:
- 最好时间复杂度:数组本身有序。在这种情况下,只需要比较(n-1) 次,而不需要做交换。时间复杂度为 O(n)
- 最坏时间复杂度: 数组完全逆序。在这种情况下,每一轮内层循环都要执行,重复的总次数是 n(n-1)/2 次,因此时间复杂度是 O(n^2)
- 平均时间复杂度:时间复杂度是 O(n^2) 。
空间复杂度:算法中只有常数项变量,O(1)O(1)。
03)代码
无优化:
function bubbleSort(arr) {
if (arr.length < 2) return arr;
let n = arr.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
document.write(bubbleSort([1,4,2,5,6,2,5,0]))
提前结束优化
function bubbleSort(arr) {
if (arr.length < 2) return arr;
let n = arr.length;
for (let i = 0; i < n; i++) {
let flag = true;
for (let j = 0; j < n - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
flag = false;
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (flag) {
break
}
}
return arr;
}
document.write(bubbleSort([1,4,2,5,6,2,5,0]))
提前结束优化 + 冒泡界优化
function bubbleSort(arr) {
if (arr.length < 2) return arr;
let flag = true;
let lastIdx = arr.length - 1;
let idx = -1;
while (flag) {
flag = false;
for (let i = 0; i < lastIdx; i++) {
if (arr[i] > arr[i + 1]) {
let temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
flag = true;
idx = i;
}
}
lastIdx = idx;
}
return arr;
}
部分参考:
作者:yukiyama 链接:https://leetcode.cn/circle/discuss/eBo9UB/ 来源:力扣(LeetCode)
|