5-2 算法与数据结构(找最小值、选择排序的递归写法)

算法入门

1.如何找到两个数中较小的数字

  • 数据结构
    用数组[a,b]表示两个数字
  • 编程知识
    问号冒号表达式 ?:
  • 代码
let minOf2 = numbers =>  //定义numbers是一个长度为2的数组
   numbers[0] < numbers[1] ? numbers[0] : numbers[1]
  • 代码优化
    析构赋值:将结构拆开,分开赋值
    直接将数组放入括号中,数组第一项命名为a,第二项命名为b
let minOf2 = ([a,b]) => a < b ? a : b
  • 调用
    minOf([1,2])
    minOf.call(null,[1,2]):(推荐这个)第一个参数是this,没有就写null

算法就是把你解决问题的思路表示出来

1.1 现成API(函数)

  • JS内置了Math.min
    Math.min(1,2) 接收两个数字
    Math.min.call(null,1,2) 不用this,call调用法
    Math.min.apply(null,[1,2]) 和call的唯一区别就是后面是数组
    注意:如果call后面加数组则是把数组当成了一项整体来看,而apply是分开来看
  • 关于Math
    看起来像Object一样的构造函数
    实际上Math只是一个普通对象
    这是唯一的特例:首字母大写是构造函数

1.2 三个数字找出最小的那个

  • 代码
    调用两次minOf(注意:不是递归,因为minOf3调用的是minOf2,不是自身)
let minOf3 = ([a,b,c]) => {
   return minOf([minOf2([a,b]),c])
}
或者
let minOf3 = ([a,b,c]) => {
   return minOf([a,minOf2([b,c])]) //推荐这种,结构看起来更美观
}
  • 推理
    任意长度数组求最小值,都可以通过minOf2实现
let minOf4 = ([a,b,c,d]) => {
   return minOf([a,minOf3([b,c,d])]) //推荐这种,结构看起来更美观
}

1.3 推广:求任意长度数组的最小值

  • 代码
    自己调用自己,这就是递归
let min = (numbers) => {
if(numbers.length > 2){
  return min(
     [numbers[0],min(numbers.slice(1))]  //slice把第一个单独拿出来和后面的一堆求最小值
  )
  }else{
     return Math.min.apply(null,numbers) //apply是把后面的数组展开
  }
}

1.4 递归

  • 特点
    1.函数不停调用自己,每次调用的参数略有不同(每次min时形式完全一样,但参数不一样)
    2.当满足某个简单条件时,则实现一个简单的调用
    3.最终算出结果
  • 理解
    可以用代入法快速理解递归
    在这里插入图片描述
    可以用调用栈快速理解递归:进入下一行就是压栈,每次缩回来就是弹栈

2.选择排序
将正整数数组从小到大排序
不断选择最小的进行排序

2.1思路

  • 用递归(更容易写出来,不能理解就用带入法)
  • 用循环

2.2 递归思路——选择排序

  • 长度为2的数组从小到大排序
    let sort2 = ([a,b]) => a < b ? [a,b] : [b,a]
  • 长度为3的数组从小到大排序
let sort3 = ([a,b,c]) => {
  let index = minIndex([a,b,c]) //minIndex返回最小值的下标
  let min = numbers[index]
  numbers.splice(index,1)//从numbers里面删掉最小值
  return [min].concat(sort2(numbers))//两个数字连接起来
}
  • minIndex
    取巧代码(后续会教其他的):
    let minIndex = (numbers) => numbers.indexOf(min(numbers))
    有bug:如果有两个最小值,就只会返回第一个最小值的下标
  • 长度为4的数组排序
let sort4 = (numbers) => {
  let index = minIndex(numbers)
  let min = numbers(index)
  numbers.splice(index,1)
  return [min].concat(sort3(numbers))
}

2.3 推广

  • 任意长度的数组排序
let sort = (numbers) =>{
  if(numbers.length > 2){
    let index = minIndex(numbers)
    let min = numbers[index]
    numbers.splice(index,1)//会返回被删除的部分
    return [min].concat(sort(numbers))
  }else{
    return numbers[0] < numbers[1] ? numbers:numbers.revers()
  }
}
  • 递归要用带入法
    在这里插入图片描述

3.代码会错——如何调试
用console.log调试

  • 调用栈
    函数调用了函数,前面一个函数就会被压到栈里去,下图就是压栈的过程
    在这里插入图片描述
  • 当代码运行结果出现错误,就把每一步的结果用console.log打出来,看哪一步结果开始不对
    注意:括号里是反引号
 console.log(`min: ${min}`)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值