选择排序
function selectionSort<Item>(a: Item[]): void {
const exch = (a: Item[], i: number, j: number): void => {
const temp: Item = a[i]
a[i] = a[j]
a[j] = temp
}
for (let i = 0; i < a.length; i++) {
let min = i
for (let j = i + 1; j < a.length; j++) if (a[j] < a[min]) min = j
exch(a, i, min)
}
}
const a = [5, 3, 6, 1, 543, 24, 56, 123, 444, 325]
selectionSort<number>(a)
console.log(a)
插入排序
function insertionSort<Item>(a: Item[]): void {
const exch = (a: Item[], i: number, j: number): void => {
const temp: Item = a[i]
a[i] = a[j]
a[j] = temp
}
for (let i = 1; i < a.length; i++) {
for (let j = i; j > 0 && a[j] < a[j - 1]; j--) {
exch(a, j, j - 1)
}
}
}
const a = [5, 3, 6, 1, 543, 24, 56, 123, 444, 325]
insertionSort<number>(a)
console.log(a)
希尔排序
function shellSort<Item>(a: Item[]): void {
const exch = (a: Item[], i: number, j: number): void => {
const temp: Item = a[i]
a[i] = a[j]
a[j] = temp
}
const N = a.length
let h = 1
while (h < N / 3) h = h * 3 + 1
while (h >= 1) {
for (let i = h; i < N; i++) {
for (let j = i; j >= h && a[j] < a[j - h]; j -= h) {
exch(a, j, j - h)
}
}
h = Math.floor(h / 3)
}
}
const a = [5, 3, 6, 1, 543, 24, 56, 123, 444, 325]
shellSort<number>(a)
console.log(a)
归并排序
自顶向下
function mergeSort<Item>(a: Item[]): void {
const exch = (a: Item[], i: number, j: number): void => {
const temp: Item = a[i]
a[i] = a[j]
a[j] = temp
}
const merge = (a: Item[], lo: number, mid: number, hi: number) => {
let b1 = lo
let b2 = mid + 1
const aux = []
for (let i = lo; i <= hi; i++) {
aux[i] = a[i]
}
for (let i = lo; i <= hi; i++) {
if (b1 > mid) a[i] = aux[b2++]
else if (b2 > hi) a[i] = aux[b1++]
else if (aux[b1] < aux[b2]) a[i] = aux[b1++]
else a[i] = aux[b2++]
}
}
const sort = (a: Item[], lo: number, hi: number) => {
if (hi <= lo) return
const mid = Math.floor((hi + lo) / 2)
sort(a, lo, mid)
sort(a, mid + 1, hi)
merge(a, lo, mid, hi)
}
sort(a, 0, a.length - 1)
}
const a = [5, 3, 6, 1, 543, 24, 56, 123, 444, 325]
mergeSort<number>(a)
console.log(a)
自底向上
function mergeBUSort<Item>(a: Item[]): void {
const exch = (a: Item[], i: number, j: number): void => {
const temp: Item = a[i]
a[i] = a[j]
a[j] = temp
}
const merge = (a: Item[], lo: number, mid: number, hi: number) => {
let b1 = lo
let b2 = mid + 1
const aux = []
for (let i = lo; i <= hi; i++) {
aux[i] = a[i]
}
for (let i = lo; i <= hi; i++) {
if (b1 > mid) a[i] = aux[b2++]
else if (b2 > hi) a[i] = aux[b1++]
else if (aux[b1] < aux[b2]) a[i] = aux[b1++]
else a[i] = aux[b2++]
}
}
const N = a.length
for (let sz = 1; sz < N; sz *= 2) {
for (let lo = 0; lo < N - sz; lo += sz * 2) {
merge(a, lo, lo + sz - 1, Math.min(lo + 2 * sz - 1, N - 1))
}
}
}
const a = [5, 3, 6, 1, 543, 24, 56, 123, 444, 325]
mergeBUSort<number>(a)
console.log(a)
快速排序
function sort<Item>(a: Item[]): void {
const exch = (a: Item[], i: number, j: number): void => {
const temp: Item = a[i]
a[i] = a[j]
a[j] = temp
}
const getRandomIndex = (lo: number, hi: number): number => {
return lo + Math.floor(Math.random() * (hi - lo + 1))
}
const partition = (a: Item[], lo: number, hi: number): number => {
exch(a, lo, getRandomIndex(lo, hi))
const v = a[lo]
let pl = lo
let ph = hi + 1
while (true) {
while (a[++pl] < v) {
if (pl === hi) break
}
while (a[--ph] > v) {}
if (pl >= ph) break
exch(a, pl, ph)
}
exch(a, lo, ph)
return ph
}
const sort = (a: Item[], lo: number, hi: number): void => {
if (lo >= hi) return
const j = partition(a, lo, hi)
sort(a, lo, j - 1)
sort(a, j + 1, hi)
}
sort(a, 0, a.length - 1)
}
const a = [5, 3, 6, 1, 543, 24, 56, 123, 444, 325]
sort<number>(a)
console.log(a)