循环执行步骤 2. ,直到 i 和 j 相遇时停止,最后将基准数交换至两个子数组的分界线(i 或 j)
时间复杂度:O(nlogn)
空间复杂度:O(logn)
稳定性:不稳定(基准元素可能被交换到相同元素的另一侧)
function sort(arr) { quickSort(arr, 0, arr.length - 1)}function quickSort(arr, left, right) { if (left >= right) return // 子数组长度为 1 时说明子数组排序完成,终止递归 const pivot = partition(arr, left, right) // 找到划分后 pivot 的位置,然后递归排序它的左右两部分 quickSort(arr, left, pivot - 1) quickSort(arr, pivot + 1, right)}// 排序函数,对数组排序,并返回排序后 pivot 的位置function partition(arr, left, right) { const pivot = arr[left] // 以最左边 left 位置的数为基准数 let i = left + 1, j = right // pivot 后面的数参与比较 // 把<=pivot的数全部放在左边,>=pivot的数全部放在右边 while (i <= j) { while (i <= j && arr[i] <= pivot) i++ while (i <= j && arr[j] >= pivot) j-- if (i < j) { [arr[i], arr[j]] = [arr[j], arr[i]] } } [arr[left], arr[j]] = [arr[j], arr[left]] // 循环结束时 j 指向最后一个小于等于 pivot 的元素,所以把它和最左边的数字(也就是 pivot)进行交换 return j // 交换后返回 pivot 的位置}
选择排序
原理:每轮从未排序区间选择最小的元素,将其放到已排序区间的末尾
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定(交换最小数时可能改变相同数的相对位置)
function selectionSort(arr) { const len = arr.length for (let i = 0; i < len - 1; i++) { // 外层循环 i:当前循环轮次要排好第 i 个位置的数 let minIdx = i // 后面未排序的数中最小值的索引 for (let j = i; j < len; j++) { if (arr[j] < arr[minIdx]) minIdx = j // 记录最小数的索引 } [arr[i], arr[minIdx]] = [arr[minIdx], arr[i]] // 最小数就是要排在第 i 个位置的数 }}