冒泡排序
冒泡排序,有时被称为下沉排序,是一种简单的排序算法,它反复遍历要排序的列表,比较每一对相邻项,如果它们的顺序错误(升序或降序排列),则交换它们。重复传递列表,直到不需要交换,这表示列表已排序。
function BubbleSort (arr) {
if (arr.length <= 1) return []
for (let i = 0; i <arr.length;i++) {
for(let j = 0; j < arr.length - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j+1]] = [arr[j+1], arr[j]]
}
}
}
return arr
}
插入排序
插入排序是一种简单的排序算法,它一次构建一个项目的最终排序数组(或列表)。与更高级的算法(如快速排序、堆排序或合并排序)相比,它在大型列表上的效率要低得多。
-
从第一个元素开始,该元素可以认为已经被排序;
-
取出下一个元素,在已经排序的元素序列中从后向前扫描;
-
如果该元素(已排序)大于新元素,将该元素移到下一位置;
-
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
-
将新元素插入到该位置后;
-
重复步骤2~5。
function insertSort (arr) { if (arr.length <= 1) return [] for (let i = 1; i < arr.length; i++) { let temp = arr[i] let j = i - 1 while (j >= 0 && temp < arr[j]) { arr[j + 1] = arr[j] j-- } arr[j+1] = temp } return arr } insertSort([4,6,1,2,3])
选择排序
选择排序是一种排序算法,特别是就地比较排序。它的时间复杂度为O(n2),使得它在大型列表上效率低下,并且通常比类似的插入排序的性能更差。选择排序以其简单性著称,在某些情况下,特别是在辅助内存有限的情况下,它比更复杂的算法具有性能优势。
-
从未排序的序列中找到最大的元素,放在已排序的序列的末尾,重复该步骤直到所有元素排序完毕
function selectionSort (arr) { if (arr.length <= 1) return [] for (let i = 0; i < arr.length - 1; i++) { let mIndex = i for (let j = i + 1; j < arr.length; j++) { if (arr[j] < arr[mIndex]) { mIndex = j } } if (mIndex !== i) { [arr[i], arr[mIndex]] = [arr[mIndex], arr[i]] } } return arr } selectionSort([4,6,1,2,3])
堆排序
let len = 0
function heapify (arr, i) {
let c1 = 2 * i + 1
let c2 = 2 * i + 2
let max = i
if (c1 < len && arr[c1] > arr[max]) {
max = c1
}
if (c2 < len && arr[c2] > arr[max]) {
max = c2
}
if (max != i) {
[arr[max], arr[i]] = [arr[i], arr[max]]
heapify(arr, max)
}
}
function heapSort (arr) {
// 创建大顶堆
len = arr.length
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i)
}
for (let i = len - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]]
len--
heapify(arr, 0)
}
console.log(arr)
return arr
}
heapSort([4,1,10,5,3,7,13,2])
快速排序
function quickSort (arr) {
if (arr.length <= 1) return arr
const compareArr = arr.splice(0, 1)[0]
let left = []
let right = []
for (let i = 0; i < arr.length; i++) {
if (arr[i] <= compareArr) {
left.push(arr[i])
} else if (arr[i] >= compareArr) {
right.push(arr[i])
}
}
return quickSort(left).concat([compareArr], quickSort(right))
}
quickSort([4,1,10,5,3,7,13,2])
归并排序
function mergeSort (arr) {
if (arr.length < 2) return arr
const len = arr.length
let middle = len >> 1,
left = arr.slice(0, middle),
right = arr.slice(middle)
return merge(mergeSort(left), mergeSort(right))
}
function merge (left, right) {
const result = []
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift())
} else {
result.push(right.shift())
}
}
while (left.length) {
result.push(left.shift())
}
while (right.length) {
result.push(right.shift())
}
return result
}
mergeSort([4,1,10,5,3,7,13,2])
希尔排序
function shellSort (arr) {
const len = arr.length
if (len < 2) return arr
let gap = len >> 1
while (gap > 0) {
for (let i = 0; i < len - gap; i++) {
let currentIndex = i
let gapShiftedIndex = gap + i
while (currentIndex >= 0) {
if (arr[gapShiftedIndex] < arr[currentIndex]) {
[arr[gapShiftedIndex], arr[currentIndex]] = [arr[currentIndex], arr[gapShiftedIndex]]
}
gapShiftedIndex = currentIndex
currentIndex = currentIndex - gap
}
}
gap = gap >> 1
}
return arr
}
shellSort([4,1,10,5,3,7,13,2])
计数排序
function countingSort (originalArray, min = undefined, max = undefined) {
let detectedMax = max || 0
let detectedMin = min || 0
if (!detectedMax || !detectedMin) {
originalArray.forEach(element => {
if (element < detectedMin) {
detectedMin = element
}
if (element > detectedMax) {
detectedMax = element
}
})
}
const buckets = Array.from({length: (detectedMax - detectedMin + 1)}).fill(0) // 创建累计数组,并填充0
let sortedArray = [] //创建回写数组
originalArray.forEach(element => buckets[element - detectedMin] += 1) // 累计数组频次计算
for (let bucketIndex = 1; bucketIndex < buckets.length; bucketIndex += 1) {
buckets[bucketIndex] += buckets[bucketIndex - 1];
}
buckets.pop();
buckets.unshift(0);
for (let i = 0; i < originalArray.length; i++) {
const element = originalArray[i]
const elementSortedPosition = buckets[element - detectedMin]
sortedArray[elementSortedPosition] = element
buckets[element - detectedMin] += 1
}
return sortedArray
}
countingSort([4,1,10,5,3,7,13,2])
基数排序
function RadixSOrt (originalArray) {
let sortedArray = [...originalArray]
const numLenth = Math.floor(Math.log10(Math.max(...originalArray))) + 1
for (let i = 0; i < numLenth; i ++) {
let buckets = Array.from({length: 10}, () => [])
const modded = 10 ** (i+1)
const divided = 10 ** i
sortedArray.forEach(element => {
if (element < divided) {
buckets[0].push(element)
} else {
const currentDigit = Math.floor((element % modded) / divided)
buckets[currentDigit].push(element)
}
})
sortedArray = buckets.reduce((acc, val) => {
console.log(acc)
return [...acc, ...val]
}, [])
}
return sortedArray
}
RadixSOrt([4,1,10,5,3,7,13,2])