每个浏览器中对排序方法的实现都不太一样
- Google的Chrome浏览器的JavaScript引擎是:V8——数组长度小于等于 10 的用插入排序InsertionSort,比10大的数组则使用快速排序 QuickSort
- Mozilla的Firefox浏览器的JavaScript引擎是:SpiderMonkey——归并排序源码
- Safari浏览器的JavaScript引擎是:Nitro(JavaScriptCore )——桶排序和归并排序
- IE浏览器的JavaScript引擎是:Chakra——使用快排
16.1 插入排序
动图演示
基本思想
从左往右遍历数组,每次将遍历的项插入到前面的已经排序好的有序数组中,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法步骤
- 默认从
i = 1
开始判断,这样preIndex
自然是内部循环的游标; current
保存arr[i]
,通过循环来确定current
的最终位置;- 每个内循环开始的时候,
arr[i] === current === arr[preIndex + 1]
,所以在内循环首次时arr[preIndex + 1]
=arr[preIndex]
的时候不必担心arr[i]
的值丢失; - 总体思路是,需要排位的元素先额外缓存起来,然后套用内循环,使得需要调整的元素赋值给它后面的一个位置上,形成依次挪位,最后因为内循环在判断条件不生效的时候停止意味着找到了需要排位的元素的正确位置,然后赋值上去,完成排序。
代码实现
function Insertion(arr) {
let len = arr.length;
let preIndex, current;
for (let i = 1; i < len; i++) {
preIndex = i - 1;
current = arr[i];
while (preIndex >= 0 && current < arr[preIndex]) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current;
}
return arr;
}
var arr = [3, 5, 7, 1, 9];
console.log(Insertion(arr))
16.2 快速排序
图片演示
基本思想
- 在数据集之中,选择一个元素作为"基准"(pivot)。
- 所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
- 对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
算法步骤
- 定义一个quickSort函数
- 检查数组的元素个数,如果小于等于1,就返回。
- 选择"基准"(pivot),并将其与原数组分离,再定义两个空数组,用来存放一左一右的两个子集。
- 开始遍历数组,小于"基准"的元素放入左边的子集,大于基准的元素放入右边的子集。
- 递归重复
代码实现
var quickSort = function (arr) {
if (arr.length <= 1) { return arr; }
// 获取基准值得索引
let pivotIndex = Math.floor(arr.length / 2);
// 获得索引值
let pivot = arr.splice(pivotIndex, 1)[0];
// 定义左右两个空数组
let left = [];
let right = [];
// 分组
for (let i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
// 递归
return quickSort(left).concat([pivot], quickSort(right));
};
// test
console.log(quickSort([1,23,42,5,2,51,2]))
优化后的代码实现
function quickSort(arr) {
return quick(arr, 0, arr.length - 1)
}
function quick(arr, left, right) {
let index
if (arr.length > 1) {
index = partition(arr, left, right)
if (left < index - 1) {
quick(arr, left, index - 1)
}
if (index < right) {
quick(arr, index, right)
}
}
return arr
}
function partition(arr, left, right) {
const pivot = arr[Math.floor((right + left) / 2)]
let i = left
let j = right
while (i <= j) {
while (arr[i] < pivot) {
i++
}
while (arr[j] > pivot) {
j--
}
if (i <= j) {
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
i++
j--
}
}
return i
}
console.log(quickSort([1, 5, 34,3,65,3,23,4,1]))
参考文章
Array.sort 算法原理(插入排序\快速排序in-place实现)
js算法-快速排序(Quicksort)
算法 3:最常用的排序——快速排序