冒泡排序是我们会经常用到的排序方法,本文记录一下冒泡排序及优化的实现方法,希望对大家有所帮助
一、 前情提要
js 中可以使用数组的原生方法 sort 来进行排序。默认排序顺序是在将元素转换为字符串,然后比较它们的 UTF-16 代码单元值序列时构建的
直接使用 sort,元素会按照转换为的字符串的诸个字符的 Unicode 位点进行排序
1 2 3
| let arr = [4,2,8,10,1]; arr.sort() console.log(arr)
|
会发现,上面的结果中,10 在 2 的前面,不过 sort 方法有一个可选参数可以传入一个函数,解决数字类型数组的排序问题
1 2 3 4 5 6 7
| let arr = [4,2,8,10,1]; function compareNumbers(a, b) { return a - b; }
arr.sort(compareNumbers) console.log(arr)
|
二、冒泡排序实现 sort
1、基础实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| let arr = [4,2,8,10,1,9,10,6,20,21,22,23]; let count = 0; function sort (arr) { for(let i=0; i < arr.length-1; i++){ for(let j=0; j < arr.length-i-1; j++){ if (arr[j] > arr[j+1]) { let tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; } count++; } } return arr } let result = sort(arr); console.log(count) console.log(result)
|
n 为数组长度,执行次数为 n(n-1)/2,时间复杂度为 O(n^2)
2、增加有序标示位
基础实现中,如果在进行到最后一轮循环之前数组已经有顺序,但是排序算法还是会执行后面的循环,所以我们可以添加一个标示,如果内层循环,没有数据交换说明已经有序,可以提前退出循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| let arr = [4,2,8,10,1,9,10,6,20,21,22,23]; let count = 0; function sort (arr) { for(let i=0; i < arr.length-1; i++){ let isSorted = true; for(let j=0; j < arr.length-i-1; j++){ if (arr[j] > arr[j+1]) { let tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; isSorted = false; } count++; } if (isSorted) { break; } } return arr } let result = sort(arr); console.log(count) console.log(result)
|
基础实现需要 66 次,如果实现有序的轮次更靠前,可以更明显。
3、增加有序标示位
第二种优化,只有在全部有序的情况下才会终止循环,如果数组已经有部分有序,还是要遍历。
为了优化这种情况,可以添加一个有序区的标示位,记录最后一次交换元素的位置。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| let arr = [4,2,8,10,1,9,10,6,20,21,22,23]; let count = 0; function sort (arr) { let lastExchangeIndex = 0; let sortBorder = arr.length - 1 for(let i=0; i < arr.length-1; i++){ let isSorted = true; for(let j=0; j < sortBorder; j++){ if (arr[j] > arr[j+1]) { let tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; isSorted = false; lastExchangeIndex = j; } count++; } sortBorder = lastExchangeIndex if (isSorted) { break; } } return arr } let result = sort(arr); console.log(count) console.log(result)
|
优化无止境,本文参考漫画算法中的代码实现。
最后
感谢各位的阅读,如有不对欢迎批评指正,共同交流。