排序算法比较
排序算法
-
冒泡排序
最简单最原始的一个个的比较排序,直接上代码
let arr = [10, -7, 3, 44, 23, 56, 73, 4, 11, 6]; function bubbleSort(arr) { let len = arr.length, temp; for (let i = 0; i < len; i++) { for (let j = i; j < len; j++) { if (arr[i] > arr[j]) { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } } bubbleSort(arr); -
选择排序
选择排序的技巧在于,每次找最小或最大的数字,将它放到合适的位置上
function select(arr) { let len = arr.length, minIndex = 0, temp; for (let i = 0; i < len; i++) { minIndex = i; for (let j = i + 1; j < len; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } select(sortArr); -
插入排序
插入排序的技巧在于,数组划分为排序跟未排序的两部分(初始化视数组首位为已排序部分),每次选择未排序的首位在已排序部分寻找合适的位置
function insert (arr) { // 初始化首位视为已排序,所以 index 是 1 let len = arr.length, prev, index = 1, temp; while (index > len) { prev = index - 1; while (prev >= 0 && arr[prev] > temp) { // 如果 跟未排序的数值对比的,比它大,则将它的位置往后移动一位 arr[prev + 1] = arr[prev]; prev--; } // 此时 temp 大于 arr[prev] 但 小于 arr[prev+1] // 如 [2,3,5,6],排序是4,那么现在arr[perv]是3,arr[prev+1]是5 // 所以插到 prev + 1 的位置上 arr[prev+1] = temp; } return arr; } -
希尔排序
希尔排序,插入排序的改进版本。
基本思想:先将这个那个待排序的记录序列分割成若干个子序列,分别对子序列进行直接插入排序,待整个序列中的记录基本有序时,再对全体进行一次的插入排序
由此可知,希尔排序的主要操作有两步:1. 分割 2. 插入排序。
function shell(arr) { let len = arr.length, s = Math.floor(len / 2), index = 0, prev, temp; while(s > 0) { index = s; while(index < len) { prev = index; temp = arr[index]; while (prev - s >= 0 && arr[prev - s] > temp) { arr[prev] = arr[prev - s]; prev -= s; } arr[prev] = temp; index += s; } s = Math.floor(s / 2); } } -
归并排序
这张图就是合并排序的思想,步骤方法。
// 不断拆分数组,直到数组长度为1,也就是图中的分的阶段
function merge(arr) {
// console.log(arr);
let len = arr.length;
if (len < 2) return arr;
let middle = Math.floor(arr.length / 2);
let left = arr.slice(0, middle),
right = arr.slice(middle);
return mergeSort(merge(left), merge(right));
}
// 左右数组对比,合并有序数组,也就是图中治的部分
function mergeSort(left, right) {
let result = [];
// left跟right其中之一可能有undefined的情况,所以要判断一下
while(left && right && left.length && right.length) {
if (left[0] < right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
// 当left,right长度不对等时,单独处理各自
while(left && left.length) {
result.push(left.shift());
}
while(right && right.length) {
result.push(right.shift());
}
return result;
}
-
快速排序
选中基准值,确定这个值在数组中的位置。
具体方法就是左右指针向中间靠拢,右指针从后往前移动,如果遇到右指针值大于基准值,则向前继续移动,直到定位在小于或等于基准值的位置;左指针从前往后移动,如果遇到小于基准值的,继续向后移动,直到定位在大于或等于基准值的位置。想要达到的效果就是,基准值的左边都是小于或等于基准值的,右边都是大于或等于基准值的。
注意点:
- 判断完成的标志
if (l >= r) return arr; - 基准值选中是首位,那么必须先从后往前寻找,一直找到小于基准值的位置,然后从前往后着,一直找到大于基准值的位置,交换两个位置的值
- 当找到跟基准值相同的值且还在循环找值时,将该左指针往前挪一位,进行下一轮的判断
- 递归便利
function qSort(arr, l, r) { // 1. 判断完成的标志 if (l >= r) return arr; let i = l, j = r, prev; // 选中基准值 let current = arr[l]; while (i !== j) { // 从后往前找 while (arr[j] > current && i < j) j--; // 从前往后着 while (arr[i] < current && i < j) i++; if (i < j) { if (arr[i] !== arr[j]) { prev = arr[j]; arr[j] = arr[i]; arr[i] = prev; } else { // 若相同,则左指针(从前往后的指针)往后挪一位,即数组的下一个位置 i++; } } } // 4. 递归 qSort(arr, 0, i-1); qSort(arr, i+1, r); } - 判断完成的标志