排序 数组塌陷 数组去重 回调函数
冒泡排序
意义
是把一个乱序的数组通过代码的执行调整为一个有序的数组
逻辑:
1. 遍历数组, 两两对比, 把相对较大的数字向后移动
2. 遍历一遍以后, 得到的结果就是最大的数字一定在最后面
3. 重复步骤1, 继续比较, 两轮以后, 最大的两个数字一定在最后两个位置
4. 不管多少个数字, 只要比较总长度 -1 轮, 那么数组就排序完成了
代码
var arr = [ 9, 1, 2, 3, 4, 5, 6, 7, 8 ] // 目的: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
console.log('原始数组 : ', arr)
for (var j = 0; j < arr.length - 1; j++) {
for (var i = 0; i < arr.length - 1 - j; i++) {
console.log('过程 : ', arr[i], ' > ', arr[i + 1], arr[i] > arr[i + 1])
if (arr[i] > arr[i + 1]) {
var tmp = arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = tmp
tmp = null
}
}
console.log('一遍以后 : ', arr)
}
console.log('排序以后以后 : ', arr)
计数排序
意义
数组排序算法的一种
逻辑
1. 准备一个新的数组
(1) 遍历原始数组, 把原始数字当做新数组的索引向新数组内填充数据
(2)新数组的数据按照计数排列
2. 遍历新数组
(1) 把索引在当做数据放进原始数组内
(2) 前提: 把原始数组清空
// 计数排序
var origin = [ 9, 3, 100, 6, 4, 100, 1, 9, 8, 7, 2, 2, 5, 100, 3, 32, 55 ]
var newarr = []
// 1. 把数据当索引
for (var i = 0; i < origin.length; i++) {
// origin[i] 就是数据
newarr[ origin[i] ] ? newarr[ origin[i] ]++ : newarr[ origin[i] ] = 1
}
// 2. newarr 中的索引当数据
// newarr 中的值当多少个
// 2-1. 清空 origin
origin.length = 0
// 2-2. 填充回去
for (var i = 0; i < newarr.length; i++) {
// i 表示真实数据
// newarr[i] 表示有多少个
if (!newarr[i]) continue
// 填充回去
// 填充 newarr[i] 个 i
for (var k = 0; k < newarr[i]; k++) origin[origin.length] = i
}
console.log('排序之后 : ', origin)
选择排序
逻辑:
1. 遍历数组, 找到数组中最小的数字, 和最前面一个数字对调
2. 从第二轮开始, 跳过第一个, 剩下的再继续重复步骤1
第 x 轮 | 外层循环控制变量 | 假设 | 里层循环开始 | 对调 | |
---|---|---|---|---|---|
1 | 0 | 0 | 1 | [0] 和 [minIndex] | |
2 | 1 | 1 | 2 | [1] 和 [minIndex] | |
3 | 2 | 2 | 3 | [2] 和 [minIndex] |
var arr = [ 8, 4, 6, 1, 3, 9, 5, 2, 7 ]
console.log('原始数组 : ', arr)
for (var j = 0; j < arr.length - 1; j++) {
// 完整书写步骤1
// 假设
var minIndex = j
// 里层循环开始
for (var i = j + 1; i < arr.length; i++) {
if (arr[i] < arr[minIndex]) minIndex = i
}
// 对调
if (j === minIndex) continue
// 代码执行到这里, 说明 j 和 minIndex 不一样
var tmp = arr[j]
arr[j] = arr[minIndex]
arr[minIndex] = tmp
tmp = null
}
console.log('排序之后 : ', arr)
数组塌陷
解释
1. 当你删除数组前面的数据的时候
2. 从你删除位置的数据开始, 后面的所有数据, 索引会先前递减
3. 我们管这个行为叫做 数组塌陷
解决问题的方向
1. 不要塌陷: 从后面删除, 倒着循环数组
2. 让循环控制变量退一步: i–
// 需求: 数组 4 个数据, 遍历每次删除当前这个, 一次一个, 删除完毕数组
var arr = [ 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4 ]
console.log('原始数组 : ', arr)
// 出现塌陷问题
// for (var i = 0; i < arr.length; i++) {
// // i 就是当前这个数据的索引
// // aplice(开始索引, 多少个)
// arr.splice(i, 1)
// }
// 解决塌陷方案1
// 倒着循环数组
for (var i = arr.length - 1; i >= 0; i--) {
// // i 依旧是数组内每一个的索引, 只不过是倒着的
arr.splice(i, 1)
}
// 解决塌陷方案2:
// i--
// 只要你执行了 splice, 就执行一个 i--
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2) {
arr.splice(i, 1)
i--
}
}
console.log('删除之后 : ', arr)
数组去重 : 去除数组内重复项
方案:
includes()
语法: 数组.includes(数据)
作用: 判断数组内是否有该数据
返回值: 布尔值
true, 说明有
false, 说明没有
// 原始数组
var arr = [ 1, 2, 3, 4, 3, 2, 1, 3, 4, 2, 1, 5, 6, 4, 3, 2, 5 ]
console.log('原始数组 : ', arr)
// 准备一个空数组
// 把原始数组进行遍历, 依次插入到新数组内
// 在插入之前进行一个判断, 新数组内有这个数据, 就不插入, 没有才插入
var newarr = []
for (var i = 0; i < arr.length; i++) {
// // arr[i] 是数组内的每一个数据
// // 如果从 arr[1] 开始后面还有 1 这个数据, 那么删除一个
if (!newarr.includes( arr[i] )) {
newarr.push(arr[i])
}
}
console.log('去重之后 : ', newarr)
回调函数 callback
概念
1.把 函数A 当做实参传递到 函数B 内
2. 在 函数B 内以形参的方式调用 函数A
此时, 我们就说 函数A 是 函数B 的回调函数
作用
1. 封装和遍历相关的内容
2. 封装和异步相关的内容