冒泡排序
- 思路:
- 用数组的每一个元素和下一个元素比较大小,如果当前的元素比下一个元素大,那就互换数组中的位置,继续和下一个比较
const popSort = arr => {
// arr.length - 1
// 因为在嵌套的排序中,通过比较大小,前后元素会互换,所以不必执行最后一次循环
// 并不是必须的,只是为了减少时间复杂度
for (let i = 0
// arr.length - 1 - i
// 原理同上
for (let j = 0
if (arr[j] > arr[j + 1]) {
let temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
return arr
}
选择排序
- 思路
- 选择排序和冒泡排序有一点像,但是区别在于
- 冒泡:每次和相邻元素比较,然后互换位置
- 选择:每次查找最小元素,然后和当前元素互换位置
let selectSort = arr => {
for (let i=0
// 用于获取满足嵌套循环条件的下标
let index = i
// 这里是关键,选择排序,只循环还未排序的数组,所以此处j 永远比i 大 1
for (let j = i + 1
// 每次满足arr[j] < arr[index] 更新index
// 比如例子传入的数组中,第一次交换的过程如下
// 外层第一次循环 元素为29,此时index = 0
// 当内层循环元素为 10 时,10 < 29,此时index=3
// 当内层循环下一步循环到 9 时,就是9 和 10 对比,此时index = 4
// 依次类推,每次循环,查找最小的元素,然后用外层循环的元素和当前获取到最小元素的位置互换
if (arr[j] < arr[index]) {
index = j
}
}
// 用获取到的下标取出当前循环的元素
// 交换当前操作的元素和满足条件的元素 的位置
let temp = arr[i]
arr[i] = arr[index]
arr[index] = temp
}
return arr
}
console.log(selectSort([29, 40, 34, 10, 9, 18]))
快速排序
- 思路:
- 取出数组的中间值,并且在此时要注意要修改元数组
- 循环数组,将比中间值小的元素放到left 数组,否则放入right 数组
- 递归调用
const quickSort = (arr) => {
if (arr.length < 2) {
return arr
}
const midIndex = ~~(arr.length / 2)
const midItem = arr.splice(midIndex, 1)
const left = []
const right = []
for (let i = 0; i < arr.length; i++) {
if (arr[i] < midItem[0]) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return [...quickSort(left), ...[...midItem, ...quickSort(right)]]
}
斐波那契数列
- 定义
- 数列第1和第2项为1,从第3项开始,每一项都等于前两项之和
- 举例
- 1、1、2、3、5、8、13、21、34、...,n
- 求第n 项的值
// 最简单的写法
let fib = (n) => {
if (n < 3) {
return 1
}
return fib(n - 1) + fib(n - 2)
}
// 上面方法重复计算次数太多,过于消耗性能
// 用数组保存每次计算的值,减少计算次数,用占用内存空间减少计算时间
const fib1 = (n) => {
const arr = []
arr[0] = 0
arr[1] = 1
for (let i = 2
arr[i] = arr[i - 1] + arr[i - 2]
}
return arr[n]
}
// 继续优化
// 减少了存储数据量,优化存储空间
const fib2 = (n) => {
let a = 0,
b = 1,
c
if(n === 0) {
return 0
}
for(let i=2
c = a + b
a = b
b = c
}
return b
}