JavaScript 算法入门

682 阅读3分钟

算法

算法是一个良定义的具体计算步骤的一个序列

一个算法就是由人或机器可重复的解决问题的方法
计算机科学家们使用算法的复杂度(又称0标记法)来表示算法的效率

通过代码来了解算法

找到2个数字中较小的一个

思路:用数组[a,b]表示2个数,使用?:表达式

let minof2 = (numbers)=>{                          
 if(numbers[0]<numbers[1]){
 return numbers[0]
 }else{ 
 return numbers[1]
 }
}

简写
let minof2 = numbers => numbers[0]<numbers[1] ? numbers[0] : numbers[1]

析构赋值写法
let minof2 =([a,b]) => a<b ? a : b

调用
minof2([1,2])               // 1    普通调用法
minof2.call(null,[1,2])     // 1    call调用法

Math.min(JS内置API)

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

看起来Math像Object一样是构造函数,实际上Math只是一个普通对象,这是唯一特例

3个数字中最小的

let minof3 = ([a,b,c])=> {
return minof2([minof2([a,b]),c])}

let minof3 = ([a,b,c])=> {
 return minof2([a,minof2([b,c])])}

4个数字中最小的

let minof4 = ([a,b,c,d])=> {
 return minof2([a,minof3([b,c,d])])}

求N个数字中的最小的

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

numbers.slice(不要numbers的第一个)
apply,不接收完整数组,apply会把numbers拆开,变成x,y

递归

直接或间接调用函数本身,则该函数称为递归函数;递归函数不能定义为内联函数

函数不停的调用自己,每次调用的参数略有不同,当满足某个简单条件时则实现一个简单的调用,
最终算出结果,求任意长度数字中最小值的代码就是递归

使用代入法理解递归

[2,4,3,1]

min([2,4,3,1])
=min([2,min([4,3,1])])
=min([2,min([4.min([3,4])])])
=min2,min4,Math.min.apply(null,[3,1])
=min2,(min4,1)
=min2,1
=1

将正整数数组从小到大排序 (用递归实现)

选择排序,将长度为2的数组排序

let sort2=([a,b])=>{
 if(a<b){
 return [a,b]
 }else{
 return [b,a]
 }
}

简写
let sort2=([a,b])=> a<b ? [a,b] : [b,a]

长度为3的数组进行排序

let sort3 = (numbers) => {
  let index =minIndex([a,b,c]) 
  let min = numbers[index]
  numbers.splice(index,x)
  return [min].concat(sort2(numbers))
}

index,最小值的下标
min,最小值下标对应的数字
从numbers里删除最小值并返回最小值
min(第一个数组),concat连接,sort2(numbers)第二个数组,得到排好序的新数组

长度为4的数组排序

let sort4 = (numbers) => {
  let index =minIndex(numbers)
  let min = numbers[index]
  numbers.splice(index,1)                          
  return [min].concat(sort3(numbers))
}

任意长度的数组排序

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)
  let min = numbers[index]
  numbers.splice(index,1)
  return [min].concat(sort(numbers))
  }else{
  return numbers[0]<numbers[1] ? numbers : numbers.revese()
  }
}

numbers.revese()取这个数组的相反的数组,把a和b调换位置

示例[12,5,8,7,9]

sort([12,5,8,7,8])
=[5]+sort([12,8,7,9])
=[5]+([7]+sort([12.8.9]))
=[5]+([7]+([8]+sort([12,9])))
=[5]+([7]+([8]+([9,12])))
=[5,7,8,9,12]