排序算法之冒泡排序
这里是传送门⇒总结:关于排序算法
平均时间复杂度 | 最优时间复杂度 | 最差时间复杂度 | 空间复杂度 | 稳定性 | |
---|---|---|---|---|---|
冒泡排序 | O(n2) | O(n2) | O(n2) | O(1) | 稳定 |
优化后 | O(n2) | O(n) | O(n2) | O(1) | 稳定 |
- 算法描述
- 从头开始,依次比较相邻元素,如果前者比较大,则交换两者位置
- 比较一轮之后,最大的元素被“冒泡”到最后
- 继续从头开始比较相邻元素,把倒数第二大的元素“冒泡”到倒数第二的位置
- ...直到所有元素都冒泡完毕
- JS实现
// 使用公用函数Swap
// 交换array[i]和array[j]
function Swap(array, i, j) {
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
// 此处传入的array会被直接改变
function BubbleSort(array) {
var len = array.length;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len - i - 1; j++) {
if (array[j] > array[j + 1]) {
Swap(array, j, j + 1);
}
}
}
}
- 分析
- 基操是键值的比较
- 不管哪种情况下,键值的比较的次数都是
- 任何情况下的时间复杂度都为T(n) = O(n2)
- 而该排序是直接交换待排序列的元素位置,即原地排序,所以空间复杂度为O(1)
- 而在相邻元素的比较中,只有当前者比后者大时才交换位置,所以一样大的元素的前后位置不会改变,即冒泡排序是一种稳定排序算法
- 优化
- 算法中加上一个didswap的变量,用来表明当前这一轮的所有键值比较中是否有需要交换位置的情况
- 让diswap一开始为false
- 当一轮比较中有任何需要交换元素的情况出现,那么就把didswap设为true
- 在一轮比较之后判断didswap的值,如果为false,那么直接结束算法了
- 因为在一轮比较之后,如果didswap还是false,这说明待排序列的相邻元素之间已经没有需要交换位置的情况了
- 也就是说相邻元素之间现在都是“前者小于等于后者”的关系,即待排序列已经是一个升序序列了
- 该优化可以把冒泡排序算法的最优时间复杂度变为O(n)
- 优化版的JS实现
// 此处传入的array会被直接改变
function BubbleSortPlus(array) {
var len = array.length;
var didswap;
for (var i = 0; i < len - 1; i++) {
didswap = false;
for (var j = 0; j < len - i - 1; j++) {
if (array[j] > array[j + 1]) {
Swap(array, j, j + 1);
didswap = true;
}
}
if (!didswap) {
break;
}
}
}