前言
掌握多种常用算法可以提升我们自身的内力,锻炼我们的逻辑思维。
交换函数
function swap(array, a, b) {
[array[a], array[b]] = [array[b], array[a]];
}
冒泡排序
//冒泡排序
function bubbleSort(array) {
const { length } = array;
for (let i = 0; i < length; i++) {
//-i的目的是随着趟数的增加,就不需要再对最后排好序的元素进行比较了
for (let j = 0; j < length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
}
}
}
return array;
}
选择排序
原地排序算法。选择排序大致的思路是找到数据结构中的最小值并 将其放置在第一位,接着找到第二小的值并将其放在第二位,以此类推
function selectionSort(array) {
const length = array.length;
let indexMin;
for (let i = 0; i < length - 1; i++) {
indexMin = i;
for (let j = i; j < length; j++) {
if (array[indexMin] > array[j]) {
indexMin = j;
}
}
if (i !== indexMin) {
swap(array, i, indexMin);
}
}
return array;
}
插入排序
插入排序每次排一个数组项,以此方式构建最后的排序数组。假定第一项已经排序了。
接着,它和第二项进行比较:第二项是应该待在原位还是插到第一项之前呢?这样,头两项就已正确排序,接着和第三项比较(它是该插入到第一、第二还是第三的位置呢),以此类推。。
排序小型数组时,此算法比选择排序和冒泡排序性能要好。
function insertionSort(array) {
const length = array.length;
let temp;
for (let i = 1; i < length; i++) {
let j = i;
temp = array[i];
while (j > 0 && array[j - 1] > temp) {
array[j] = array[j - 1];
j--;
}
array[j] = temp;
}
return array;
}
希尔排序
希尔排序是第一个突破O(n²)的算法,是基于插入排序的算法,通常情况都是好于O(n²)
function shellSort(array) {
const length = array.length;
//间隔
let gap = (length / 2) | 0;
while (gap >= 1) {
//以gap作为间隔分组,然后插入排序;
for (let i = gap; i < length; i++) {
let temp = array[i];
let j = i;
while (j > gap - 1 && array[j - gap] > temp) {
array[j] = array[j - gap];
j -= gap;
}
array[j] = temp;
}
gap = Math.floor(gap / 2);
}
}
归并排序
归并排序是第一个可以实际使用的排序算法 归并排序性能不错,其复杂度为 O(nlog(n))
例如,Mozilla Firefox使用了归并排序作为 Array.prototype.sort 的实现
归并排序是分治法,递归的,我们要将算法分成两个函数,第一个函数是将大数组切分为多个小数组并调用排序的辅助函数
function mergeSort(array) {
//归并排序将一个大数组转化为多个小数组直到其中只有一个项。由于算法是递归的,我们需要一个停止条件,在这里此条件是判断数组的长度是否为 1
if (array.length > 1) {
const { length } = array;
const middle = Math.floor(length / 2);
const left = mergeSort(array.slice(0, middle));
const right = mergeSort(array.slice(middle, length));
array = merge(left, right);
}
return array;
}
function merge(left, right) {
let i = 0;
let j = 0;
const result = [];
while (i < left.length && j < right.length) {
result.push(left[i] > right[j] ? left[i++] : right[j++]);
}
return result.concat(i < left.length ? left.slice(i) : right.slice(j));
}
二分查找
这个算法要求是被搜索的数据结构是已排序的 过程是:
1.选择数组的中间值
2.如果选中值是待搜索值,那么直接返回,算法执行完毕
3.如果待搜索值比选中值要小,则返回步骤一并在选中值左边的子数组中寻找(较小)
4.如果待搜索值比选中值要大,则返回步骤一并在选中值右边的子数组中寻找(较大)
function binarySearch(array, target) {
let low = 0;
let high = array.length - 1;
while (low <= high) {
const mid = Math.floor((low + high) / 2);
const middleValue = array[mid];
if (middleValue > target) {
high = mid - 1;
} else if (middleValue < target) {
low = mid + 1;
} else {
return mid;
}
}
return -1;
}
结语
以上就是常用的排序方法了