JavaScript 递归选择排序

99 阅读1分钟

选择排序

在未排序序列中找到最小元素,放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

找出两个数中较小的项
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.call(null,[1,2])
找出三个数中最小的项
let minOf3 = ([a,b,c]) => {
  return minOf2(minOf2[a,b],c)
}
找出四个数中最小的项
let minOf4 = ([a,b,c,d]) => {
  return minOf2(minOf2(minOf2[a,b],c),d)
}

经过推理可以得出,求任意长度的数组的最小值都可以用 minOf2 实现

找出任意长度数组的最小项

let min = (numbers) => {
  if (numbers.length > 2) {
    return min([numbers[0], min(numbers.slice(1))])
  } else {
    return minOf2.call(null,numbers)
  }
}
长度为2的数组排序
let sort2 = ([a,b]) => {
  if(a >b){
    return [b,a]
  }else{
    return [a,b]
  }
}
长度为3的数组排序
let minIndex = (numbers) =>{
  return numbers.indexOf(min(numbers))
}
let sort3 = numbers => {
  let index = minIndex(numbers)
  let min = numbers[index]
  numbers.splice(index,1)
  return [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))
}

任意长度的数组都可以多次调用排序,只要把sort2,sort3,sort4都改成sort,就是递归排序

递归选择排序

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 sort2(numbers)
  }
}

总结

  1. 每次运算都要有返回值,否则会 undifined
  2. 要有条件终止递归,否则会无限循环
  3. 递归运算时的参数类型应该与定义时保持一致
  4. 递归如果理解不了,就用代入法找规律
  5. 所有的递归都可以改写成循环