第 54 题:冒泡排序如何实现,时间复杂度是多少, 还可以如何改进?
时间复杂度: n^2
// 生成从l到r的数量为n的随机数组 function randomArr (n, l, r) { let arr = []; for (let i = 0; i < n; i++) { let _random = Math.round(l + Math.random() * (r - l)); arr.push(_random) } return arr; } function buddleSort (arr) { let len = arr.length; for (let i = len; i >= 2; i-- ) { for (let j = 0; j < i - 1; j++) { if (arr[j] > arr[j+1]) { [arr[j], arr[j+1]] = [arr[j+1], arr[j]]; } } } return arr; } console.log(buddleSort(randomArr(10, 5, 100)));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(28)
长知识了~
根据上述代码,我们每一轮冒泡需要的结果就是把最大的数通过冒泡放到最后,然后缩小下一轮需要冒泡的数组的范围(未优化的方案中数组范围只缩小了一位),但是实际上我们每一轮冒泡后可能会出现后面的几个数都有序的情况,这个时候我们完全可以再缩小一点下一次需要冒泡的数组的范围(不然下一轮冒泡到最后发现最大的数本来就在最后,此次冒泡就是多余的)。那怎么确定这个i值呢?
举个栗子:
[a[0],...,a[j],a[j+1],...,a[i]]
如果某一次冒泡比较中a[j]>a[j+1]
交换两值,此时a[j+1]大于a[0]到a[j]的任何值(a[0]到a[j]还是无序的)
如果再接下来的冒泡中满足a[j+1]到a[i]有序,即不做任何交换操作(a[j]和a[j+1]是最后一次交换操作)
那我们下一轮只需要对a[0]到a[j]的无序数组进行冒泡排序,j就是下一轮循环的i值
@wwwxy80s 我这边的冒泡排序的改良思路是,如果某一次遍历,没有进入过if条件,则表示已经是排好的顺序了,跳出循环
时间复杂度: O(n^2)
一般的冒泡:
这个存在的问题是,每次循环一次,后面就会多一段有序的数组,然而每次还是遍历了,是多余了
优化一下这个问题
对于这个方案,还可以改进
如果剩下的还没有排序的部分,本身就是有序的,也可以让遍历跳过,就又可以省下不少时间
例如这种:
let a = [1, 2, 3, 4, 5, 6, 3, 11, 12, 9, 5, 8, 7, 23, 6, 8, 9];
普通:冒泡排序
改良:鸡尾酒排序(就是先向上冒个泡,再向下冒个泡,如此重复)
标准实现中的 j < arr.length - i - 1; 循环条件不已经达到这个目的了吗??
这个改进版 是不是 每次取最后一次调换位置的下标 作为 下一次循环的长度?????
不一样的 改良版的可以跳跃的 j < arr.length - i - 1 标准的是 每次都是一次递减的,不管是不是存在部分冒泡好的
另一种写法:
冒泡排序概念:依次比较相邻的两个元素,如果顺序倒置则交换相邻元素。
每次最大值放到最右后,会将本轮最后一个操作的位置作为下一轮的终点,可以减少不必要的一些冒泡
arr = [5,4,22,33,11,66]
arr.sort(function(a,b){
return a-b })
console.log(arr)
练个手
时间复杂度 O(n^2)
@guokangf 这个改良算法能解释一下吗?
bubble
我喜欢
冒泡排序
时间复杂度(大O计数法):O(n^2)
补充一个
刚好这有一篇文章解答了今天面试题https://www.jianshu.com/p/5d44186b5263