本文正在参加「金石计划 . 瓜分6万现金大奖」
数据结构:数据的存储方式,算法:同一问题的不同解决方法!
1. 冒泡
const arr = [5, 4, 3, 1, 2]
for (let i = 0; i < arr.length - 1; i++) {
let flag = true
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
flag = false
;[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
}
}
if (flag) break // 代表未曾进去过,说明已经排好了
console.log('次数测试')
}
console.log(arr)
1. 洗牌
原理:遍历数组元素,将当前元素与以后随机位置的元素进行交换!
const arr = [9, 1, 10, 2, 7, 0, 4, 5, 6, 3, 8]
const shuffle = (arr) => {
let i = arr.length
while (i) {
const j = Math.floor(Math.random() * i--)
;[arr[j], arr[i]] = [arr[i], arr[j]]
}
}
shuffle(arr)
console.log(arr)
2. 选择
每次找到最大或最小的索引与当前外层索引交换位置!与冒泡不同的是它不是每比较就交换,而是一轮比较完毕再交换!
const arr = [3, 5, 4, 1, 2]
for (let i = 0; i < arr.length; i++) {
let min = i // 假设最小索引
// 检查是否还有更小的索引
for (j = i + 1; j < arr.length; j++) {
// 这里必须是 arr[min],而不能是 arr[i],因为 min 是会变化的,i 是不会变化的
if (arr[j] < arr[min]) {
min = j
}
}
// 假设失败,则交换位置
if (min !== i) {
;[arr[i], arr[min]] = [arr[min], arr[i]]
}
}
console.log(arr)
3. 快排
找中间数,比中间数小的放左数组,大的放右数组,递归 return fn(leftArr).concat(cenValue, fn(rightArr));
const arr = [5, 3, 4, 1, 2]
function fn(arr) {
// #1 条件
if (arr.length <= 1) return arr
// #2 中数
// 从 start 开始,删除 1 个,返回的是一个数组,影响原数组
let cenValue = arr.splice(Math.floor(arr.length / 2), 1)[0]
// #3 和中数比较
let leftArr = []
let rightArr = []
for (let i = 0; i < arr.length; i++) {
if (arr[i] < cenValue) {
leftArr.push(arr[i])
} else {
rightArr.push(arr[i])
}
}
// #4 返回
return fn(leftArr).concat(cenValue, fn(rightArr))
}
console.log(fn(arr))
4. 归并
先拆分再比较再合并
const arr = [38, 27, 43, 3, 9, 82, 10]
const marge = (before = [], after = []) => {
console.log(before, after, 'start')
const temp = []
// 当两个数组都有元素时候才进行循环比较 循环移除 标记最小值
while (before.length && after.length) {
// 取出首位
const [m] = before
const [n] = after
// 首位做比较 取最小值临时存储 且将最小值从源数组中移除
temp.push(m > n ? after.shift() : before.shift())
}
console.log(before, after, 'end', temp)
// 将其余位放到最小位后面(合并)
return temp.concat(before).concat(after)
}
const sort = (arr = []) => {
if (!Array.isArray(arr)) throw new Error('arg is not an Array')
if (arr.length <= 1) return arr
// 递归二分数组 直到数组中的元素个数小于等于1 (拆分)
const splitIndex = Math.floor(arr.length / 2)
const before = arr.slice(0, splitIndex)
const after = arr.slice(splitIndex)
return marge(sort(before), sort(after))
}
console.log(sort(arr))