The introduction of
Converts an unordered column of data to an ordered state. Such as:
Numerical order: 5,8,12,23,30,56,68,…..
Dictionary order: an, boy, cow, yellow,…..
classification
Classification by complexity
O(n^2):
- Insertion sort
- Comparison sort
- Bubble sort
O(nlgn):
- Merge sort
- Quick sort
- Block sorting
O (n), O (nk) :
- Bucket sort
- Radix sort
Comparison/Others
Based on comparison:
- Insertion sort
- Comparison sort
- Bubble sort
- Merge sort
- Quick sort
- Block sorting
Other:
- Bucket sort
- Radix sort
According to whether to open up a new space classification
In place (do not open up memory space in place swap) :
- Insertion sort
- Comparison sort
- Bubble sort
- Quick sort
The place:
- Merge sort
- Bucket sort
- Block sorting
- Radix sort
implementation
Binary search
Imagine: If you are a teacher, in a pile of papers, you want to find a certain paper, how would you do, in order to find it in the shortest time.
abstract
function bsearch(A, x)
AAn array of:x: Returns the value to be found:x 在 AIn, there is no return -1Copy the code
Cyclic invariant
Before the loop: L: left edge of the search range r: right edge of the search range GUESS: L, middle position of R After the loop: L: left edge of the new search range R: right edge of the new search range GUESS: The new l, r middle position at the end of each loop, the value that we're looking for is either between positions L and R, or it doesn't existCopy the code
Program implementation
// Search a list of sorted numbers, return index if found, return -1 if not found
function bSearch(A, x) {
let l = 0,
r = A.length - 1,
guess
while(l <= r) {
guess = Math.floor((l + r)/2)
if(A[guess] === x) return guess
else if(A[guess] < x) l = guess + 1
else r = guess - 1
}
return -1
}
let arr = [1.2.5.11.12.16]
console.log(bSearch(arr, 11)) // The result is: 3
Copy the code
Insert sort
Imagine this: if your hand is in order, grab one card at a time and insert it into place.
Question: How do I insert a new value into an ordered array and then keep it ordered
Function abstraction
function insert(A, x)
A: sorted arrayx: Returned value of the element to be inserted: NoneCopy the code
First edition:
const A = [2.4.7.9.13] /** Original array */
const x = 8 /** The element to insert */
const index = A.indexOf(b)
A.splice(index === -1 ? A.length : index, 0, x)
console.log(A) // [2, 4, 7, 8, 9, 13]
Copy the code
Cyclic invariant
P: points to the next element to be compared. P +1: points to the space vacated. I: points to the next element to be sortedCopy the code
The second version:
function insert(A, i, x) {
let p = i - 1
while(A[p] > x) {
A[p + 1] = A[p]
p--
}
A[p + 1] = x
}
function insert_sort(A) {
for (const i of A.keys()) {
insert(A, i, A[i])
}
}
const A = [1.2.100.11.12.16]
insert_sort(A)
console.log(A) // [1, 2, 11, 12, 16, 100]
Copy the code
Bubble sort
You can imagine, under a lake, you have a bunch of bubbles of different sizes coming up, and which of them is going to get to the surface first because physics says the biggest one gets to the surface first
Problem: according to the principle of bubbling to achieve sorting…
Problem abstraction:
function bubble_sort(A)
A: The array to sort returns: noneCopy the code
Cyclic invariant
Outer loop invariant: after the KTH loop, the first k values are sorted in position I. After the loop is executed, position I and the value to its right are in the sorted state inner loop invariant: at the end of each loop, the control variable j points to the largest value in the 0-j elementCopy the code
Program implementation:
function swap(A, i, j) {
const temp = A[i]
A[i] = A[j]
A[j] = temp
}
function bubble_sort(A) {
for (let i = A.length; i >= 1; i--) {
for (let j = 1; j <= i; j++) {
A[j - 1] > A[j] && swap(A, j - 1, j)
}
}
}
const A = [1.2.100.11.8.16]
bubble_sort(A)
console.log(A) //[1, 2, 8, 11, 16, 100]
Copy the code
Merge sort
Problem: The implementation keeps splitting the array and then merging it
Problem abstraction:
function merge(A, p, q, r)
AAn array of:p: left half starting positionq: Left half end, right half start positionr: End on the right sideCopy the code
Cyclic invariant:
I: points to the next element to be put back in A1. J: points to the next element to be put back in A2. K: points to the next writeback position in ACopy the code
Program implementation:
function merge(A, p, q, r) {
const A1 = A.slice(p, q)
const A2 = A.slice(q, r)
A1.push(Number.MAX_SAFE_INTEGER)
A2.push(Number.MAX_SAFE_INTEGER)
for (let k = p, i = 0, j = 0; k < r; k++) {
A[k] = A1[i] < A2[j] ? A1[i++] : A2[j++]
}
}
function merge_sort(A, p, r) {
if(r - p < 2) return
let q = Math.ceil((r + p)/2)
merge_sort(A, p, q)
merge_sort(A, q, r)
merge(A, p, q, r)
}
const A = [1.2.60.19.8.16]
merge_sort(A) // [1, 2, 8, 16, 19, 60]
merge_sort(A, 3.5) // [1, 2, 60, 8, 19, 16]
Copy the code
Quick sort
Split the array by center, putting values <= center to the left and values greater than center to the right
Problem abstraction:
function partition(A, lo, hi)
A: The array to sortlo: Starting position (Closed interval)
hi: End position (Open interval) return: center location Side effect: [lo.hiDivided into two areas by a central pointfunction qsort(A)
A: The array to sort returns: noneCopy the code
Cyclic invariant:
We need to determine: <= center point: [LO, I) undefined: [I, j) greater than center point: [j, hi) Center point: hi-1Copy the code
Program implementation:
function partition(A, lo, hi) {
const pivot = A[hi - 1]
let i = lo, j = hi -1
while(i ! == j) { pivot >= A[i] ? i++ : swap(A, i, --j) } swap(A, j, hi -1)
return j
}
function swap(A, i, j) {
[A[i], A[j]] = [A[j], A[i]]
}
function qsort(A, lo = 0, hi = A.length) {
if (hi - lo < 2) return
let pivot = partition(A, lo, hi)
qsort(A, lo, pivot)
qsort(A, pivot + 1, hi)
}
const A = [100.2.60.19.8.16]
qsort(A) // [2, 8, 16, 19, 60, 100]
Copy the code
Counting sort
Iterate over the original array, accumulative write accumulative array. Then add and accumulate the array to get the element position.
Problem abstraction:
function counting_sort(A)
A; The array to be sorted returns: result arrayCopy the code
Program implementation:
function counting_sort(A) {
const max = Math.max(... A)// Accumulate the array
const B = Array(max + 1).fill(0)
// Result array
const R = Array(A.length)
// Cumulative array increment
A.forEach((_, i) = > B[A[i]]++)
// Add the sum
for (let i = 1; i < B.length; i++) {
B[i] += B[i-1]}for (const i of A.keys()) {
const p = B[A[i]] - 1 // Write back position
B[A[i]]-- // New write position
R[p] = A[i] // Write back the result
}
return R
}
const A = [9.2.60.19.8.16]
console.log(counting_sort(A)) //[2, 8, 9, 16, 19, 60]
Copy the code
Radix sort
Sort integers by grouping values of the same significant digit.
Problem abstraction:
function radix_sort(A) {
for (let i ofThe number of digits in A ()) {sort by the ith significant digit of the left number A}}Copy the code
Program implementation:
function radix_sort(A) {
const max = Math.max(... A)const buckets = Array.from({ length: 10 }, () = > [])
// Significant digits
let m = 1
while(m < max) {
// Put the array into the bucket
A.forEach( num= > {
const digit = ~~ ( ( num % ( m * 10 )) / m )
buckest[digit].push(num)
})
// Fetch the element from the bucket
let j = 0
buckets.forEach( bucket= > {
while(bucket.length > 0) {
A[j++] = bucket.shift()
}
})
// Next position
m *= 10}}const A = [9.2.600.19.8.16]
radix_sort(A )
console.log((A)) // [2, 8, 9, 16, 19, 600]
Copy the code
Bucket sort
Counting sort is a special kind of bucket sort.
Problem abstraction:
function bucket_sort(A, K, S)
A: The array to sortK: Number of bucketsS: Size of each bucket returns: sorted arrayCopy the code
Program implementation:
function bucket_sort(A, K, S) {
const buckets = Array.from({ length: K }, () = > [])
// Put it in the bucket
for (let i of A.keys()) {
const index = ~~(A[i] / S)
buckets[index].push(A[i])
}
// Sort each bucket
for (let i of buckets.keys()) {
insertion_sort(buckets[i])
}
// Retrieve data
return[].concat(... buckets) }function insertion_sort(A) {
for (let i = 1; i < A.length; i++) {
let p = i - 1
const x = A[p+1]
while(p >= 0 && A[p] > x) {
A[p+1] = A[p]
p--
}
A[p+1] = x
}
}
const A = [9.2.600.19.80.16]
console.log(bucket_sort(A, 10.100)) // [2, 9, 16, 19, 80, 600]
Copy the code
External sort
Usage scenario: Large hard disk, small memory.
For example: need to sort 600M data, at this time only 300M memory, and the hard disk has 500GB…
For external sort, the performance of sorting algorithm is no longer the biggest bottleneck; The bottleneck of the algorithm is data read and write (I/O). Since memory reads and writes occur in nanoseconds, hard disk reads and writes occur in milliseconds, and hard disk reads and writes are a physical process
External sorting occurs on disk, not in memory.