两数中找出较小的那个

代码

  1. var minOf2 = (numbers)=>{
  2. if(numbers[0] < numbers[1]){
  3. return numbers[0]
  4. }else{
  5. return numbers[1]
  6. }
  7. }

优化代码

  1. let minOf2 = numbers => numbers[0] < numbers[1] ? numbers[0] : numbers[1]

继续优化(解构赋值

  1. let minOf2 = ([a, b]) => a<b ? a:b

调用:

  1. minOf2([1,2])
  2. minOf2(null,[1,2])//推荐这种写法

使用现成的API

JS 内置了 Math.min
调用方法:

  1. Math.min(1,2)//1
  2. Math.min.call(null,1,2)
  3. Math.min.apply(null,[1,2])

关于Math

  • 看起来 Math像 Object一样是构造函数
  • 实际上Math只是一个普通对象
  • 这是唯一的特例:首字母大写是构造函数


三数中找出最小的那个

  1. let minOf3 = ([a,b,c]) => {
  2. return minOf2([minOf2[a,b],c])
  3. }

或者

  1. let minOf3 = ([a,b,c]) => {
  2. return minOf2([a, minOf2([b,c])])
  3. }

推理:

  1. let minOf4 = ([a,b,c,d]) => {
  2. return minOf2([a, minOf3([b,c,d])])
  3. }

找出最小的那个

递归:

  1. let min = (numbers) => {
  2. if(numbers.length > 2){
  3. return min([numbers[0], min(numbers.slice(1))])
  4. }else{
  5. return Math.min.apply(null, numbers)
  6. }
  7. }

递归:

特点

  • 函数不停调用自己,每次调用的参数略有不同
  • 当满足某个简单条件时,则实现一个简单的调用
  • 最终算出结果

理解

  • 可以用代入法快速理解递归
  • 可以用调用栈快速理解递归

长度为2 的数组排序

代码

  1. let sort2 = ([a,b]) => {
  2. if(a<b){
  3. return [a,b]
  4. }else{
  5. return [b,a]
  6. }
  7. }

优化代码

  1. let sort2 = ([a,b]) => a<b ? [a,b]:[b,a]

长度为3 的数组排序

代码

  1. let sort3 = (numbers) => {
  2. let index = minIndex(numbers)
  3. let min = numbers[index]
  4. numbers.splice(index,1)
  5. return [min].concat(sort2(numbers))
  6. }

minIndex

  1. let minIndex = (numbers) => numbers.indexOf(min(numbers))

任意长度的排序

  1. let sort = (numbers) => {
  2. if(numbers.length > 2){
  3. let index = minIndex(numbers)
  4. let min = numbers[index]
  5. numbers.splice(index,1)
  6. return [min].concat(sort(numbers))
  7. }else{
  8. return numbers[0]<numbers[1] ? numbers : numbers.reverse()
  9. }
  10. }

思路:

  • 找到最小数的索引
  • 索引对应的值
  • 删除最小值
  • 对剩下的部分重复前面步骤

    选择排序的循环写法(时间复杂度n^2)

    将 minIndex 用循环写

    1. let minIndex = (numbers) => {
    2. let index = 0
    3. for(let i = 1; i<numbers.length; i++){
    4. if(numbers[i]<numbers[index]){
    5. index = i
    6. }
    7. }
    8. return index
    9. }

所有递归都可以改写成循环

把 sort 用循环写

思路:
每次在数组中找到最小的数放在前面,然后对后面的数做重复的事情

比如:
[3,5,2,1]
先找1,然后把1跟3换位置 => [1] + [5,2,3]
然后在 [5,2,3] 中找最小数 2 ,然后跟5换位置 => [1,2] + [5,3]
然后在 [5,3] 中找最小数 3,然后跟5 换位置 => [1,2,3] + [5]

  1. let sort = (numbers) => {
  2. for(let i = 0; i < numbers.length; i++){
  3. let index = minIndex(numbers.slice(i)) + i
  4. if(index !== i){
  5. swap(numbers, index, i)//交换index,i 对应值的位置
  6. }
  7. }
  8. return numbers
  9. }
  1. let swap = (array, i, j) => {
  2. let temp = array[i]
  3. array[i] = array[j]
  4. array[j] = temp
  5. }