冒泡排序
function buttleSort(arr) { const len = arr.length; if (len <= 1) return arr; for(let i = 0; i < len; i++) { let flag = true; // 从前往后冒泡,所以已经处理的数据不用再访问 // 由于每次遍历都会访问 j + 1项;等于提前遍历了后一项 // 所以终止条件是 len - i - 1; for(let j = 0; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; flag = false; } } // 当前循环排序没有改变,flag=true,数组排序完成; if (flag) return arr; } return arr;}
快排
/** * * @param arr Number[] 待排序数组 */function quickSort(arr) { _quick(arr, 0, arr.length - 1); console.log(arr);}/** * * @param arr Number[] * @param left Number 左边界 * @param right Number 右边界 * 对 arr[l...r] 部分进行快速排序 */function _quick(arr, left, right) { if (left >= right) { return; } let index = partition(arr, left, right); _quick(arr, left, index - 1); _quick(arr, index + 1, right);}/** * * @param arr Number[] * @param left Number 左边界 * @param right Number 右边界 * @returns Number 索引值p,使得arr[left...p] < arr[p] < arr[p+1...right] * 对 arr[l...r] 部分进行快速排序 */function partition(arr, left, right) { let index = left; let target = arr[left]; for(let i = left + 1; i <= right; i++) { if (arr[i] < target) { // 如果当前值小于基准值的话,就交换到index + 1的位置去 swap(arr, i, index + 1); index++; } } // 把基准值交换至所有小于基准值的后边 既 index swap(arr, left, index); return index;}function swap(arr, i, j) { const temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;}
快排-三路
/** * 三路快排,将arr[l...r] 分为 < v; === v; > v 三部分 * 之后递归的对 < v, > v 两部分三路快排 * @param arr Number[] */function quickSort(arr) { _quick(arr, 0, arr.length); return arr;}/** * @param arr Number[] * @param left Number 左边界 * @param right Number 右边界 * 对 arr[l...r] 部分进行快速排序 */function _quick(arr, l, r) { if (l >= r) return; let [lb, rb] = partition(arr, l, r); _quick(arr, l, lb); _quick(arr,rb, r);}/** * @param arr Number[] * @param left Number 左边界 * @param right Number 右边界 * @returns [lb, rb] Number[], 返回索引值[lb, rb],使得arr[l...lb] < arr[lb] < arr[rb...r] * 对 arr[l...r] 部分进行快速排序 */function partition(arr, left, right) { let leftBound = left; // arr[left + 1...leftBound] < target let rigthBound = right + 1; // arr[rigthBound...r] > target let index = left + 1; let target = arr[left]; while(index < rigthBound) { if (arr[index] < target) { swap(arr, index, leftBound + 1); leftBound++; index++ } else if (arr[index] > target) { swap(arr, index, rigthBound - 1); rigthBound--; } else { index++ } } swap(arr, left, leftBound); return [leftBound - 1, rigthBound];}function swap(arr, i, j) { const temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;}
快排-空间
function quickSort(arr) { const len = arr.length; if (len <= 1) return arr; const left = []; const right = []; const tag = arr[0]; for(let i = 1; i < len; i++) { if (arr[i] < tag) { left.push(arr[i]) } else { right.push(arr[i]) } } return [...quickSort(left), tag, ...quickSort(right)]}
选择排序
/** * 选择排序:每一次从待排序数组中,选择最小(大)的元素作为首元素,直到排完 * @param arr number[] 待排序数组 * * 1、有 n 个元素,由于内循环每次获取 i+1 的元素,因此外循环 n-1 次; * 2、选择最小(大)的元素,放到每次循环的第一位; * 3、重复过程至 n-1位 */function selectSort(arr: number[]) { const len = arr.length; if (len <= 1) return arr; for (let i = 0; i < len - 1; i++) { let temp = i; for (let j = i + 1; j < len; j++) { if (arr[j] < arr[temp]) { temp = j; } } if (temp !== i) { sawp(arr, temp, i); } } return arr;}
插入排序
/** * 插入排序:通过构建有序数组、对于未排序的数据,在已排序的数组中从后往前比较,找到合适的位置插入; * @param arr number[] 待排序数组 * * 1、从第一个元素开始,此元素被认定为已被排序; * 2、从第二个元素开始,在已排序的数组中从后往前比较; * 3、如果内循环 while 的 arr[pre] 元素大于外循环 for 的 arr[i] 元素,将该元素移至 pre+1; * 4、while循环内重复步骤3,直至找到 pre < 0 或 arr[pre] <= arr[i]; * 5、for循环; */function insertSort(arr: number[]) { const len = arr.length; if (len <= 1) return arr; for (let i = 0; i < len; i++) { const cur = arr[i]; let pre = i - 1; while (pre >= 0 && arr[pre] > cur) { sawp(arr, pre + 1, pre); pre--; } // 由于跳出 while 循环的条件为:pre < 0 或 arr[pre] <= cur // 所以当前循环的 arr[i] 应该插入至 pre + 1; // arr[pre + 1] = cur; // 因为 while 是在有序数组内进行循环,所以初始 arr[pre+1] 就是 cur } return arr;}
归并排序
function mergeSort(arr: number[]) { const len = arr.length; if (len <= 1) return arr; const mid = Math.ceil(len / 2); const left = arr.splice(0, mid); const right = arr.splice(mid); const leftA = mergeSort(left); const rightA = mergeSort(right); return merge(leftA, rightA);}function merge(left: number[], right: number[]) { const res: any[] = []; while (left.length && right.length) { if (left[0] <= right[0]) { res.push(left.shift()); } else { res.push(right.shift()); } } while (left.length) { res.push(left.shift()); } while (right.length) { res.push(right.shift()); } return res;}