快速排序
💬 确定基准值,遍历数组,将大于基准值的值放到后面,小于基准值的值放在前面
🎉 针对内部
双边递归
const quick_sort = (nums) => {
const sort1 = function(arr, left, right) {
if (left > right) return
let i = left, j = right
const pivot = arr[i]
while (i<j) {
while (i<j && arr[j] >= pivot) {
j--
}
arr[i] = arr[j]
while (i<j && arr[i] <= pivot) {
i++
}
arr[j] = arr[i]
}
arr[i] = pivot
sort1(arr, left, i-1)
sort1(arr, i+1, right)
}
sort1(nums, 0, nums.length-1)
return nums
}
单边递归
STL优化点
- 单边递归法
- 无监督partition方法
- 三点取中法
- 小数据规模,停止快排过程
- 使用插入排序进行首尾
归并排序
💬 将两部分有序数组合并成一个
分别将两个指针指向两个数组的第一个节点,比较两个数组,值较小的放入新空间中,指针向后移动一位
排序后的数组放入原数组内
🎉 针对外部,进行分治
二路归并
const merge_sort = (nums, l, r) => {
if (l>=r) return
let mid = (l+r) >> 1, temp = []
merge_sort(nums, l, mid)
merge_sort(nums, mid+1, r)
let k=0, p1 = l, p2 = mid + 1
while (p1 <= mid || p2 <= r) {
if ((p2 > r) || (p1 <= mid && nums[p1] <= nums[p2])) {
temp[k++] = nums[p1++]
} else {
temp[k++] = nums[p2++]
}
}
for (let i=l; i<=r; i++) {
nums[i] = temp[i-l]
}
return nums
}
多路归并
计数排序
💬 统计每一种数据的个数
🎉 简单的单值排序问题,排序问题中的数据值域很有限
基数排序
- 对个位的数据计数,求出前缀和,得到区域尾坐标
- 从后扫描数组,元素放入数组中,坐标对应前缀和中的值,归位,前缀和值减一
- 位数向前移动重复第一、第二步
const radix_sort = (nums) => {
let cnt = new Array(65536).fill(0)
let temp = new Array(nums.length)
for(let i=0;i<nums.length;i++) cnt[nums[i] & 0xffff] += 1 // 统计低16位个数
for (let i=1;i<65536;i++) cnt[i] += cnt[i-1] // 前缀和
for (let i=nums.length-1;i>=0;i--) temp[--cnt[nums[i] & 0xffff]] = nums[i]
cnt = new Array(65536).fill(0) // 重置
for(let i=0;i<temp.length;i++) cnt[(temp[i] & 0xffff0000) >> 16] += 1 // 统计高16位个数
for (let i=1;i<65536;i++) cnt[i] += cnt[i-1] // 前缀和
for (let i=nums.length-1;i>=0;i--) nums[--cnt[(temp[i] & 0xffff0000) >> 16]] = temp[i]
}
拓扑排序
拓扑序不唯一
- 将入度为0的节点都放入队列中
- 依次出队列,将当前元素指向的节点入度减一
- 将入度变为0的节点放入队列中
- 直至队列为空
const topology_sort = (numCourses, prerequisites) => {
let queue = [], deg = new Array(numCourses).fill(0), ans = []
for (x of prerequisites) {
if (!deg[x[0]]) deg[x[0]] = []
deg[x[0]].push(x[1])
}
for (let i=0;i<deg.length;i++) {
if (!deg[i]) {
queue.push(i)
}
}
while(queue.length) {
let course = queue.shift()
for (let i=0;i<deg.length;i++) {
if (deg[i] && deg[i].includes(course)) {
deg[i].splice(deg[i].indexOf(course), 1)
if (!deg[i].length) queue.push(i)
}
}
}
if (ans.length - numCourses) ans = []
return ans
}