冒泡排序:顾名思义,这是一种给无序数组排序的方法,可以把无序数组排列成由大到小或由小到大的顺序,由于其排序过程就像水中产生的气泡一样最终总会浮到水面上一样,所以叫做冒泡排序。
最简单的冒泡排序
使用双层循环,每次把内层循环的下标为j的值与外层循环下标为i的值比较
let arr = [1, 3, 6, 4, 7] // 先声明一个无序数组
for (let i = 0; i < arr.length - 1; i++) { // 获取该数组的第一个值
for (let j = i + 1; j < arr.length; j++) { // 循环获取该数组除了第一个值外的所有值
if (arr[j] < arr[i]) { // 比较值的大小,若第一个值大于后面的某个值,则交换位置,最终实现由小到大排序
let temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
结果
交换的过程
完成了最简单的冒泡排序,接下来我们可以换种思路简单升级一下冒泡排序。
使用双层循环,每次把内层循环的下标为j的值与相邻的下标为j+1的值比较
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) { // 这里 -i是减去已经排好序的个数 每一轮都会把最大的元素放到最后面
if (arr[j] > arr[j + 1]) { // 相邻元素两两对比 前一个比后一个大就交换位置
var temp = arr[j + 1]; // 元素交换
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
交换的过程
这种交换方式每一轮都会把最大的元素放到最后面,外层循环的i每次增加1后,内存循环的终止条件j < arr.length - 1 - i都减1,减少了循环比较的次数!
我们再完善一下功能并封装一下
如果传入的是数组,才进行冒泡排序。
如果某次外层循环执行完后,一次交换都没发生,这证明之后两两相邻的数字都是小的在前面,即a<b<c<d<e。此时已经完成了排序,由于没有发生交换,没有执行内层循环中的kaiguan = false;
if (kaiguan) { break; }中kaiguan=true,执行break结束循环,不再进行之后的比较。
function maoPaoSort(arr) {
if (!Array.isArray(arr)) { // 当传入参数是数组时才执行之后的代码,否则执行return阻止后续代码运行
return;
}
let kaiguan = true; //是否是已经有序
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) { // 这里 -i是减去已经排好序的个数 每一轮都会把最大的元素放到最后面
if (arr[j] > arr[j + 1]) { // 相邻元素两两对比 前一个比后一个大就交换位置
var temp = arr[j + 1]; // 元素交换
arr[j + 1] = arr[j];
arr[j] = temp;
kaiguan = false;
}
}
if (kaiguan) { // 优化:如果是本身就是有序的,那么就不需要再继续循环了。
break;
}
}
}