JavaScript冒泡排序
1)核心思路:依次比较两个相邻的值,如果后面的比前面的小,则将小的元素排到前面。依照这个规则进行多次并且递减的迭代,直到顺序正确。
- 平均时间复杂度O(n*n)
- 最好情况O(n)
- 最差情况O(n*n)
- 空间复杂度O(1)
- 稳定性:稳定
2)算法描述
1. 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
3. 针对所有的元素重复以上的步骤,除了最后一个;
4. 重复步骤1~3,直到排序完成。
var arr = [6, 5, 3, 1, 8, 7, 2, 4];
//第一趟
for (var i = 0; i < arr.length - 1; i++) {
var temp;
// 两两之间 相互比较
if(arr[i] > arr[i + 1]) {
// 大的往后排 交换
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
// 第二趟
for (var i = 0; i < arr.length - 1; i++) {
var temp;
// 两两之间 相互比较
if(arr[i] > arr[i + 1]) {
// 大的往后排 交换
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
...
这个代码执行n - 1次就可以得到结果,但是重复了很多冗余代码,于是我们利用双重for循环来代替。
for (var j = 0; j < arr.length - 1; j++) {
for (var i = 0; i < arr.length - 1; i++) {
var temp;
// 两两之间 相互比较
if(arr[i] > arr[i + 1]) {
// 大的往后排 交换
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
上述代码基本实现排序,但是不是最优化,因为次数多循环了。
第一次循环 j=0 循环 7次 arr.length - 1 - j
第二次循环 j=1 循环 6次 arr.length - 1 - j
第三次循环 j=2 循环 5次 arr.length - 1 - j
第四次循环 j=3 循环 4次 …
第五次循环 j=4 循环 3次
第六次循环 j=5 循环 2次
第七次循环 j=6 循环 1次
for (var j = 0; j < arr.length - 1; j++) {
for (var i = 0; i < arr.length - 1 - j; i++) {
var temp;
// 两两之间 相互比较
if(arr[i] > arr[i + 1]) {
// 大的往后排 交换
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
趟数的优化:因为数组的特殊性
有可能在排列到某一轮的时候就已经完成了,所以需要进行检测。 如果在整个一轮中,都没有发生交换,意味着已经完成排序了。
for (var j = 0; j < arr.length - 1; j++) {
var flag = '没有交换';
for (var i = 0; i < arr.length - 1 - j; i++) {
var temp;
// 两两之间 相互比较
if(arr[i] > arr[i + 1]) {
flag = '交换了';
// 大的往后排 交换
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
if (flag == '没有交换') {
break;
}
}
传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者) , 从而使排序趟数几乎减少了一半。
改进之后的算法如下:
var low = 0;
var high = arr.length-1;
var temp;
while(low < high){//找到最大值
for(var j = low ; j < high ; j++){
if (arr[j]> arr[j+1]) {
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
--high;//修改high值,向前移一位
}
while(low > high){//找到最小值
for(var j = high ;j > low; j--){
if (arr[j]> arr[j+1]) {
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
++low;//修改low值,往后移动一位
}