数组排序算法
- 排序的稳定性:相等的两个值在排序后,不会更改相对的前后位置
- 排序算法分为比较排序和非比较排序,本文介绍的是前者
1. 冒泡排序
- 相邻的两个元素比较,前面的元素如果大于后面的元素,则换位置。最大的元素最先排序到数组后面
- 稳定排序
function bubbleSort(arr) {
const len = arr.length
let flag = false
if (len < 2) {
return arr
}
for (let i = 0; i < len; i++) {
flag = false
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
const temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
flag = true
}
}
if (!flag) {
break
}
}
return arr
}
2. 插入排序
- 总是把元素插入到已排序数组的最后,然后再一直向前扫描,直到前面的那个元素不再大于它或者索引为0时才结束
- 稳定排序
function insertSort(arr) {
const len = arr.length
if (len < 2) {
return arr
}
let prevIndex = 0
let currValue = 0
for (let i = 1; i < len; i++) {
prevIndex = i - 1
currValue = arr[i]
while (prevIndex >= 0 && arr[prevIndex] > currValue) {
arr[prevIndex + 1] = arr[prevIndex]
prevIndex--
}
arr[++prevIndex] = currValue
}
return arr
}
3. 选择排序
- 总是选择最小值到已排序数组的后面
- 不稳定排序
function selectSort(arr) {
const len = arr.length
if (len < 2) {
return arr
}
let minIndex = 0
let temp = null
for (let i = 0; i < len - 1; i++) {
minIndex = i
for (let j = i + 1; j < len; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j
}
}
temp = arr[minIndex]
arr[minIndex] = arr[i]
arr[i] = temp
}
return arr
}
4.归并排序
- 利用递归和分而治之的思想,把数组分成两个子数组,分别排序之后再合并
- 稳定排序
function mergeSort(arr) {
function merge(left, right) {
const result = []
while (left.length > 0 && right.length > 0) {
if (left[0] <= right[0]) {
result.push(left.shift())
} else {
result.push(right.shift())
}
}
while (left.length > 0) {
result.push(left.shift())
}
while (right.length > 0) {
result.push(right.shift())
}
return result
}
const len = arr.length
if (len < 2) {
return arr
}
const middle = Math.floor(len / 2)
const left = arr.slice(0, middle)
const right = arr.slice(middle)
return merge(mergeSort(left), mergeSort(right))
}
5. 快速排序
- 与归并排序类似的思想,利用了分治和递归
- 先要找到一个基准值,大于基准值的部分是一个数组,小于的又是一个数组,等于基准值得部分推到两边都可以,然后再将这两个数组递归即可。
const quickSort = function (arr) {
const len = arr.length
if (len < 2) {
return arr
}
//寻找基准值
const index = Math.floor(len / 2)
const pivot = arr.splice(index, 1)[0]
//分治
const left = []
const right = []
for (let item of arr) {
if (item <= pivot) {
left.push(item)
} else {
right.push(item)
}
}
return [...quickSort(left), pivot, ...quickSort(right)]
}
6. 堆排序
- 构建二叉树来排序
- 稳定排序
let len = 0; // 因为声明的多个函数都需要数据长度,所以把len设置成为全局变量
function buildMaxHeap(arr) { // 建立大顶堆
len = arr.length;
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i);
}
}
function heapify(arr, i) { // 堆调整
const left = 2 * i + 1
const right = 2 * i + 2
let largest = i;
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) {
swap(arr, i, largest);
heapify(arr, largest);
}
}
function swap(arr, i, j) {
const temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function heapSort(arr) {
buildMaxHeap(arr);
for (let i = arr.length - 1; i > 0; i--) {
swap(arr, 0, i);
len--;
heapify(arr, 0);
}
return arr;
}
速记
参考文档
结语
如果对你有帮助的话,请点个赞吧