冒泡排序(n2)
第一层循环遍历外层 length -1个项,对前length-1 个数排序
内层循环遍历到length - i -1,对前length - i -1个数冒泡
function bubbleSort(arr) {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
const temp = arr[j + 1]
arr[j + 1] = arr[j]
arr[j] = temp
}
}
}
选择排序(n2)
从乱序区中选择最小加入顺序区
外层循环:扩展乱序区域到length-1
内层循环:选择乱序区域中最小下标
function selectSort(arr) {
for (let i = 0; i < arr.length - 1; i++) {
let minIndex = i
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j
}
}
const tmp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = tmp;
}
}
插入排序(n2)
从乱序区中随便选一个,找到其在乱序区域中的位置
外层循环 :扩展有序区域,到length-1
内层循环:在有序区中找到插入的位置
用pre和current辅助寻找位置
function insertionSort(arr) {
for (let i = i; i < arr.length - 1; i++) {
let preIndex = i - 1
let current = arr[i]
while (preIndex > 0 && arr[preIndex] > current) {
arr[preIndex + 1] = arr[preIndex]
preIndex--
}
}
arr[preIndex + 1] = current
}
希尔排序(nlogn~nlog2n)
用gap将数组拆分,每一小数组再进行插入排序
外外层循环:gap每次折一半,直至gap为0
function shellSort(arr) {
for (let gap = Math.floor(arr.length); gap > 0; gap = Math.floor(arr / 2)) {
for (let i = gap; gap < arr.length; i++) {
const curr = arr[i]
let j = i
while (j - gap > 0 && arr[j-gap] >curr) {
arr[j]=arr[j-gap]
j=j-gap
}
arr[j]=curr
}
}
}
归并排序(nlogn)
标准分治法,划分为两个数组,递归解决。
function mergeSort(arr) {
function sort(arr, left, right) {
if (left < right) {
const mid = (left + right) / 2
leftArr = sort(arr, left, mid)
rightArr = sort(arr, mid + 1, right)
return merge(leftArr, rightArr)
}
return left > 0 ? [arr[left]] : []
}
function merge(leftArr, leftArr) {
const res = []
const leftPtr = 0
const rightPtr = 0
while (leftPtr < leftArr.length && rightPtr < rightArr.length) {
if (leftArr[leftPtr] < leftArr[rightPtr]) {
res.push(leftArr[leftPtr++])
} else {
res.push(rightArr[rightPtr++])
}
}
while (leftPtr < leftArr.length) {
res.push(leftArr[leftPtr++])
}
while (rightPtr < rightArr.length) {
res.push(rightArr[rightPtr++])
}
return res
}
}
快速排序(nlogn-n2)
分治法,选取首个元素,将数组分为大于元素的一组和小于元素的一组。递归解决
主要包括四个步骤
后往前,找比x小
交换
前往后,找比x大
交换
function quickSort(arr) {
function sort(arr, low, high) {
let i = low
let j = high
const x = arr[low]
while (i < j) {
while (i < j && arr[j] > x) {
j--
}
if (i < j) {
arr[i] = arr[j]
i++
}
while (i < j && arr[i] < x) {
i++
}
if (i < j) {
arr[j] = arr[i]
j--
}
}
arr[i] = x
sort(arr, low, i - 1)
sort(arr, i + 1, high)
}
}
计数排序(n+k)
确定数组范围,开辟连续的空间,一次存储,按照空间顺序读取
类似哈希表,将下标作为数值存入
// 计数排序
function countingSort(arr) {
let maxValue = Number.MIN_VALUE
let minValue = Number.MAX_VALUE
const res = []
// 确定空间
arr.forEach(num => {
maxValue = num > maxValue ? num : maxValue
minValue = num > minValue ? minValue : num
})
if (minValue < 0) {
offset = -minValue
}
const bucket=new Array(maxValue+offset+1).fill(0)
// 存入对应下标
arr.forEach(num=>{
bucket[num+offset]++
})
bucket.forEach((store,index)=>{
while(store--){
res.push(index-offset)
}
})
return result
}
基数排序
对每一位放入不同的桶中