算法入门
首先解决一个求最小值问题
先考虑两个数值的最小值
用到数组数据结构
function minOf2(numbers) {
if (numbers[0] < numbers[1]) {
return numbers[0];
} else {
return numbers[1];
}
}
- 值得一提的是JS内置了一个函数求最小值,Math.min,但是min不接受数组只接受一个个参数列表
- 这个Math看起来很像构造函数,其实他不是,它是少数不符合命名规则的函数
- Math.min.apply(null,[1,2]),apply和call的唯一区别就在于apply接受 参数数组,把数组展开传入函数
- 在写minOf3之前先了解一下析构赋值,可以简化代码
- 解构赋值语法是一种 Javascript表达式。通过解构赋值,可以将属性/值从对象/数组中取出,赋值给其他变量。
- 解构赋值在表达式左边定义了要从原变量中取出什么变量。
var a, b;
[a, b] = [10, 20];
({ a, b } = { a: 10, b: 20 });
minOf2简化为
function minOf2([a,b]) {
if (a < b) {
return a;
} else {
return b;
}
}
接着考虑三个最小值
function minOf3([a, b, c]) {
return minOf2([a, minOf2([b, c])]);
}
接着考虑任意个数最小值
function min(numbers){
return min(
numbers[0],min(numbers.slice(1))
)
}
先写好主体,中止条件后面再考虑
function min(numbers){
if(numbers.length > 2){return min([
numbers[0],min(numbers.slice(1))
])}
else{
return minOf2.call(null,numbers)
}
}
递归:定义时调用自己,设置一个条件每次调用,会往满足条件的方向靠拢,关键在于理解函数和函数调用的区别
现在解决一个排序问题
长度为2的数组排序
function sort2([a,b]){
if(a < b){
return [a,b]
}else{
return [b,a]
}
}
长度为3的数组排序
function sort3([a,b,c]){
return [min([a,b,c]),sort2(???)]
}
产生了一个问题没法知道剩下的是什么
如下代码细节可以不用太追究minIndex之后单个实现
function sort3(numbers) {
let index = minIdex(numbers);
//得到最小值得下标
let min = numbers[index];
numbers.splice(index, 1);
return [min].concat(sort2(numbers));
}
长度任意的数组排序
先写下面代码,中止条件后面实现
function sort(numbers) {
let index = minIdex(numbers)
let min = numbers[index]
numbers.splice(index,1)
return [min].concat(sort(numbers))
}
在加入中止条件
function sort(numbers) {
if(numbers.length > 2){
let index = minIdex(numbers)
let min = numbers[index]
numbers.splice(index,1)
return [min].concat(sort(numbers))
}else{
if(numbers[0] < numbers[1]){
return numbers
}else{
return numbers.reverse()
}
}
}
- splice()返回的是被削的值不是剩下的
- 现在实现minIdex,用数组API实现,indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
let minIndex = (numbers) => {
return numbers.indexOf(min(numbers))
}
总结
写递归时,中止条件先别写,细节先省略