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

Six, four kinds of sorting time complexity