选择排序跟冒泡排序非常类似,唯一的区别就是选择排序每次遍历时,将各个元素比较,将最大值或最小值的索引存放在一个变量中,全部比较完了以后,再将该索引上的元素进行就交换。简单来说就是选择排序是每次遍历交换一次,而冒泡排序每次遍历需要交换多次,因此选择排序一般来说是要比冒泡排序效率高一点的。
同样的,我们来看一下选择排序(从小到大排序)的动图展示:
我们来看一下选择排序的代码封装
function selectionSort(arr) {
// 封装交换元素的函数,方便后面调用
function exchange(v1, v2) {
let temp = arr[v1]
arr[v1] = arr[v2]
arr[v2] = temp
}
// 获取传入数组的长度
let length = arr.length
// 1. 设定遍历的范围
for(let i = 0; i < length - 1; i ++) {
// 2. 先将遍历的起始索引设为最小值的索引
let min = i
// 3. 从索引为min的后一个值开始遍历全部元素
for(let j = min; j < length; j ++) {
// 3.1 将每个遍历到的元素与arr[min]比较
if(arr[min] > arr[j]) {
min = j
}
}
// 4. 将得到的最小值的索引min上的元素与我们初始遍历的位置上的元素交换
exchange(min, i)
}
// 返回排序后的数组
return arr
}
我们来测试一下该方法是否正确
let arr = [45, 66, 1, 19, 34, 80, 2]
console.log(selectionSort(arr));
// 打印结果:[1, 2, 19, 34, 45, 66, 80]
在了解了选择排序与冒泡排序的区别后,我们应该能清楚得知道,选择排序的比较次数跟冒泡排序一样,因此选择排序的比较次数用大O表示法表示为 O(n²)
选择排序每遍历一次数组,就只需要交换一次数据,因此其交换次数用大O表示法表示为 O(n)
总结:
-
选择排序的比较次数:O(n²)
-
选择排序的交换次数:O(n)
===============================================================
插入排序是一种将指定元素与某个有序区域元素比较并交换位置的排序算法。
我们先简单举个例子,假设现在有这样一个无序数组
首先,我们把索引为0的元素看作区域,该区域是有序的,因为就只有一个元素,怎样排序都是它一个元素,所以就认为它是有序的。
然后我们取出有序区域右边的第一个元素,即索引为1的元素 67
,存到变量 temp
中。然后从有序区域的最右边开始,将元素依次与变量 temp
中的元素 67
比较,若大于67,则将位置向右移动一格;若小于67,则不需要继续遍历了,因为该区域是有序的。
第一次遍历的动图:
此时的有序区域为 索引0 ~ 索引1
这部分,所以我们将索引为2的元素取出,跟有序区域的元素比较
第二次遍历的动图:
此时的有序区域为 索引0 ~ 索引2
这部分,所以我们将索引为3的元素取出,跟有序区域的元素比较
第三次遍历的动图:
此时的有序区域为 索引0 ~ 索引3
这部分,所以我们将索引为4的元素取出,跟有序区域的元素比较
第四次遍历的动图:
此时整个数组都是有序区域了,这就是一个完整的插入排序
接下来我们来封装一个插入排序的函数
function insertionSort(arr) {
// 获取传入数组的长度
let length = arr.length
// 1. 从索引为1的元素开始向后遍历数组
for(let i = 1; i < length; i ++) {
// 2. 取出有序区域右边第一个元素
let temp = arr[i]
let j = i
// 3. 从右往左将有序区域内的元素与temp比较
while(arr[j - 1] > temp && j > 0) {
arr[j] = arr[j - 1]
j –
}
// 4. 将temp插入到合适的位置
arr[j] = temp
}
// 返回排序后的数组
return arr
}
我们来测试一下该函数是否正确
let arr = [45, 66, 1, 19, 34, 80, 2]
console.log(insertionSort(arr));
// 打印结果:[1, 2, 19, 34, 45, 66, 80]
插入排序每次遍历时,比较次数和元素的移动次数都是不确定,那我们就按最坏的情况来考虑。
第一次遍历:比较次数为1,元素移动次数为1;
第二次遍历:比较次数为2,元素移动次数为2;
……
第N次遍历:比较次数为N,元素移动次数为N;
所以,插入排序的比较次数为 1 + 2 + …… + n
,元素的移动次数也和比较次数一样,那么我们对其取个平均值,也就是 (n² - n)/4
,用大O表示法表示为 O(n²)
总结:
-
插入排序的比较次数:O(n²)
-
插入排序的元素移动次数:O(n²)
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
最后
由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)**
[外链图片转存中…(img-WO6BJjiY-1710706759464)]
最后
[外链图片转存中…(img-3GO4W1ro-1710706759464)]
[外链图片转存中…(img-Sk6rbnhN-1710706759464)]
由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容