Find the smallest number of an arbitrary length array
1.1 Find the smallest of two numbers
let minOf2 = ([a,b]) = > a < b ? a : b
/ / call:
minOf2.call(null[1.2]) // The first argument to call is this, set to null
Copy the code
JS has a ready-made API: math.min
Math.min(1.2) / / 1
Math.min.call(null.1.2)
Math.min.apply(null[1.2])// The difference between apply and call is that the last half of the former is an array
Copy the code
- Math looks like a constructor like Object, but it’s just a normal Object
- This is the only special case: constructors are capitalized
1.2 Find the smallest of the three numbers
let minOf3 = ([a,b,c]) = > {
return minOf2([minOf2([a,b]),c])
}
// Deduce the smallest of the four numbers
let minOf4 = ([a,b,c,d]) = > {
return minOf2([a,minOf3([b,c,d])])
}
// minOf2 can be used to minimize arrays of any length
Copy the code
1.3 Finding the minimum number of an arbitrary length array
let min = (numbers) = > {
if(numbers.length > 2) {return min([numbers[0],min(numbers.slice(1)))}else{
return Math.min.apply(null,numbers)
}
}
// This is recursion
Copy the code
Characteristics of recursion:
-
The function keeps calling itself, with slightly different arguments each time
-
When a simple condition is met, a simple call is made
-
And then we get the answer
How to understand recursion:
- Substitution to understand recursion
- The call stack understands recursion
Second, selection sort
2.1 Recursive thinking
2.1.1 Sort arrays of length 2
let sort2 =([a,b]) = >
a < b ? [a,b] :[b,a]
Copy the code
2.1.2 Sorting arrays of length 3
let minIndex = (numbers) = > numbers.indexOf(min(numbers));
let sort3 = (numbers) = > {
let index = minIndex(numbers) // Returns the minimum subscript
let min = numbers[index] // The smallest value in numbers
numbers.splice(index, 1)// Delete the smallest number from number
return [min].concat(sort2(numbers))// Put the smallest number first, then join the following number
}
Copy the code
2.1.3 Sorting arrays of length 4
let sort4 = (numbers) = > {
let index = minIndex(numbers)
let min = numbers[index]
numbers.splice(index, 1)
return [min].concat(sort3(numbers))
}
Copy the code
2.1.4 Finding the length of an arbitrary array
let min = (numbers) = > {
if(numbers.length > 2) {return min([numbers[0],min(numbers.slice(1)))}else{
return Math.min.apply(null,numbers)
}
};
let minIndex = (numbers) = > numbers.indexOf(min(numbers));
let sort = (numbers) = > {
if(numbers.length > 2) {let index = minIndex(numbers) // Returns the minimum subscript
let min = numbers[index]// The smallest value in numbers
numbers.splice(index, 1)// Delete the smallest number from number
return [min].concat(sort(numbers))// Put the smallest number first, then join the following number
}else{
return numbers[0]<numbers[1]? numbers :numbers.reverse() } }Sort ([12,5,8,7,9])
Copy the code
2.2 Circular thinking
2.2.1 Implement sort with a loop
let sort = (numbers) = > {
for(let i=0; i< numbers.length -1; i++){
console.log(` - `) // This is the essence of the log
console.log(`i: ${i}`)
let index = minIndex(numbers.slice(i))+ i
// If the last loop found the first minimum number, then we can ignore the first number when we look for the next number
//+ I, if I is not added, the new array subscript returned by nums. slice(I) always starts at 0
console.log(`index: ${index}`)
console.log(`min: ${numbers[index]}`)
if(index! ==i){ swap(numbers, index, i)console.log(`swap ${index}: ${i}`)
console.log(numbers)
}
}
return numbers
}
// Swap the positions of two numbers in an array
let swap = (array, i, j) = > {
let temp = array[i]
array[i] = array[j]
array[j] = temp
}
// The loop implements the smallest number of subscripts
let minIndex = (numbers) = > {
let index = 0 // Assume that the minimum number subscript is 0
for(let i=1; i<numbers.length; i++){
if(numbers[i] < numbers[index]){
index = i
}
}
return index
}
Copy the code
Conclusion:
- All recursions can be changed to loops
- But the loop has a lot of details:
- The boundary conditions
- Arrays of length 0 and 1
- Debug to see the console, learn to play log, play log pay attention to the mark
Quicksort
Recursive thinking
let quickSort = arr= >{if (arr.length <= 1) { returnarr; }let pivotIndex = Math.floor(arr.length / 2); // Select a baseline
let pivot = arr.splice(pivotIndex, 1) [0];letleft = [];letright = [];for (let i = 0; i < arr.length; i++){if(arr[I] < pivot) {left.push(arr[I])}else[I] {right. Push (arr)}}return quickSort(left).concat([pivot], quickSort(right) )
}
Copy the code
Merge sort
Recursive thinking
let mergeSort = arr= >{
if(arr.length === 1) {return arr}
let left = arr.slice(0.Math.floor(arr.length/2))// The left half of the array
let right = arr.slice(Math.floor(arr.length/2))// The right half of the array
return merge(mergeSort(left), mergeSort(right))
}
let merge = (a, b) = > {
if(a.length === 0) return b
if(b.length === 0) return a
return a[0] > b[0]? [b[0]].concat(merge(a, b.slice(1))) :
[a[0]].concat(merge(a.slice(1), b))
}
Copy the code
5. Counting sort
Ideas:
- Use a hash table for the record
- If you find the number N, write it as N:1. If you find it again, add 1
- Finally, I print out all the keys in the hash table, so if N:m, then N needs to be printed m times
let countSort = arr= >{
let hashTable = {}, max = 0, result = []
for(let i=0; i<arr.length; i++){ // go through the number group
if(! (arr[i]in hashTable)){
hashTable[arr[i]] = 1
}else{
hashTable[arr[i]] += 1
}
if(arr[i] > max) {max = arr[i]}
}
for(let j=0; j<=max; j++){ // iterate over the hash table
if(j in hashTable){
for(let i = 0; i<hashTable[j]; i++){// If j occurs more than once, it is iterated
result.push(j)
}
}
}
return result
}
Copy the code
- Using extra Hashtables facilitates only one array and one hashTable, trading space for time