循环执行步骤 2. ,直到 i 和 j 相遇时停止,最后将基准数交换至两个子数组的分界线(i 或 j)
时间复杂度:O(nlogn)
空间复杂度:O(logn)
稳定性:不稳定(基准元素可能被交换到相同元素的另一侧)
function quickSort(arr, left, right) { if (left >= right) return // 子数组长度为 1 时说明子数组排序完成,终止递归 const index = partition(arr, left, right) // 找到划分后 pivot 的位置,然后递归排序它的左右两部分 quickSort(arr, 0, index - 1) quickSort(arr, index + 1, right)}// 排序函数,对数组排序,并返回排序后 pivot 的位置function partition(arr, left, right) { const pivot = arr[left] // 以最左边 left 位置的数为基准数 let i = left + 1, j = right // pivot 后面的数参与比较 while (i < j) { while (i < j && arr[j] > pivot) j-- while (i < j && arr[i] <= pivot) i++ [arr[i], arr[j]] = [arr[j], arr[i]] } [arr[left], arr[i]] = [arr[i], arr[left]] // i === j 时,它们共同指向的这个数字一定是小于 pivot 的,所以把它和最左边的数字(也就是pivot)进行交换 return i}
选择排序
原理:每轮从未排序区间选择最小的元素,将其放到已排序区间的末尾
时间复杂度: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 个位置的数 }}