二分法求数组最大最小_求数组最小值 & 4种排序方法

一、求数组最值 &排序 & 求最值下标

  1. 1请写一个 min 函数,要求 min(numbers)能返回数组 numbers 中的最小数字。
let min = (numbers) => {
  if(numbers.length > 2){
    return min(
      [numbers[0], min(numbers.slice(1))]
    )
  }else{
    return Math.min.apply(null, numbers)
  }
}

1.2 请写一个 max 函数,要求 max(numbers) 能返回数组 numbers 中的最大数字。

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

let b = max ([12,4,2,5])
console.log(b)

2.1 请写出一个 sort 函数,要求 sort(numbers) 能返回一个把 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.reverse()
  }
}

2.2 请写出一个 sort 函数,要求 sort(numbers) 能返回一个把 numbers 从大到小排列的数组

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

let maxIndex = (numbers) =>
  numbers.indexOf(max(numbers))

let reverse = (numbers) => {
  if(numbers.length > 2){
    let index = maxIndex(numbers)
    let max = numbers[index]
    numbers.splice(index, 1)
    return [max].concat(reverse(numbers))
  }else{
    return numbers[0] > numbers[1] ? numbers :numbers.reverse()
  }
}

let a = reverse.call(null,[12,11,10,9,8,7])
console.log(a)

3. 查找数组中最小值的下标

let index =(numbers) =>{
  let index = 0
  for(i = 1;i < numbers.length;i++){
    if(numbers[i]<numbers[index])
      index = i;     
  }
  return index
}

let a = index.call(null,[12,13,14,11,9,6,7])
console.log(a) // 5

二、 4种排序方法

  • 选择排序
    • 在数组中找到最小值的下标,和当前的换位置,排除这个最小值后,再从剩下的数组中找最小的,互换下标~
    • 时间复杂度O(n^2)
let minIndex =(numbers) =>{
  let index = 0
  for(i = 1;i < numbers.length;i++){
    if(numbers[i]<numbers[index])
      index = i;     
  }
  return index
}

let  swap = (numbers, index, i) =>{
  let temp = numbers[index]
      numbers[index] = numbers[i]
      numbers[i] = temp
}

let sort = (numbers) =>{ 
    for(let i=0;i<numbers.length-1;i++){
      
        console.log(`--------`)
        console.log(`i:${i}`)
        
        let index = minIndex(numbers.slice(i))+i
        
          console.log(`index:${index}`)
          console.log(`min: ${numbers[index]}`)
          
        if(index!=i){
          swap(numbers, index, i)
          console.log(`swap: ${index}: ${i}`)     
        }  
       console.log(numbers)
      }
  return numbers
}

let c = sort.call(null,[2,13,4,5,16])
 console.log(`最终结果:`)
 console.log(c) // [2,4,5,13,16]

去掉 console.log 版

//循环,排序 小——大
let minIndex =(numbers) =>{
  let index = 0
  for(i = 1;i < numbers.length;i++){
    if(numbers[i]<numbers[index])
      index = i;     
  }
  return index
}

let  swap = (numbers, index, i) =>{

  let temp = numbers[index]
      numbers[index] = numbers[i]
      numbers[i] = temp
}

let sort = (numbers) =>{ 
    for(let i=0;i<numbers.length-1;i++){
          let index = minIndex(numbers.slice(i))+i          
          if(index!=i){
              swap(numbers, index, i)            
          }  
    }
  return numbers
}

let c = sort.call(null,[2,13,4,5,16])
 console.log(c) 
  • 快速排序
    • (找个中间数,比他大放在右,比他小放在左)
    • 时间复杂度 O(n log2 n)
//快速排序 [1,12,8,9,19,4]

let quickSort = (numbers) =>{
  if(numbers.length <= 1){return numbers}
  let pivotIndex = Math.floor(numbers.length/2)
    console.log(`----------`)
    console.log(`pivotIn: ${pivotIndex}`)
  let pivot = numbers.splice(pivotIndex,1)[0]
  console.log(`pivot: ${pivot}`)
  let left = []
  let right = []
   for(let i=0;i<numbers.length;i++){
       if(numbers[i]<pivot){
         console.log(numbers[i])
         left.push(numbers[i])
         console.log(`left:${left}`)
       }else{
         right.push(numbers[i])
         console.log(`right:${right}`)
       }
   }
       return quickSort(left).concat([pivot],quickSort(right))
}
let c = quickSort.call(null,[1,12,8,9,19,4])
console.log(c)
let pivot = numbers.splice(pivotIndex,1) [0]
因为: numbers.splice(pivotIndex,1) 返回的是数组 如:[9], 在后面加 [0],才是数字 9
if(numbers.length <=1){return numbers} 这句关键要加上
  • 归并排序 (merge sort)
    • 没有基准,左边一半自觉排好序,右边一半自觉排好序,两边从小的依次对比,然后左右两边合并(merge)起来。
    • 时间复杂度 O(n log2 n)

70d0c591b67b1ef29fc9ce146ad918df.png
图片来源 饥人谷教学课件
//插 冒 归 基

//快 选 堆 希

//归并排序 [1,12,8,9,19,4]
//左右分队  归1 再merge

let mergeSort = (arr) =>{
    if(arr.length===1){
      return arr
    }
    let left = arr.slice(0,Math.floor(arr.length/2))
    let right = arr.slice(Math.floor(arr.length/2))
    return merge(mergeSort(left),mergeSort(right))
  }
  
  let merge = (a,b) =>{
    if(a.length === 0){return b}
    if(b.length === 0){return a}
    return a[0]<b[0]? [a[0]].concat(merge(a.slice(1),b)):[b[0]].concat(merge(a,b.slice(1)))
  }
  
 let c = mergeSort.call(null,[1,12,8,9,19,4])
return 后面不能换行!!!,巨坑,别再踩了!!! 注意:return [a[0]].concat~
  • 计数排序(哈希)
    • 像找扑克牌一样,A 4个放在一起,2放4个在一起,一直到K...
    • 时间复杂度O(n+max-min)
//计数排序
let CountSort = (arr) =>{
    let result = [], HashTable = {}, max = 0
    for(let i=0;i<arr.length;i++){
    if(!(arr[i] in HashTable)){
      HashTable[arr[i]] = 1
    }else{
      HashTable[arr[i]] += 1
    }
      //找最大值
      if(arr[i]>max){
        max = arr[i]
      }
    }

//遍历哈希表 (最小到最大的数字)
      for(let j=0;j <= max;j++){
        if(j in HashTable){
          for(let z=0;z<HashTable[j];z++){
                result.push(j)
          }
        }
      }
      return result
  }
    let a = CountSort.call(null,[1,3,2,4,2,2,5,6,6,14,1,8,4,9,12])
    console.log(a)
console.log(HashTable[2])
表示数组中的2 ,出现了几次
所以使用HashTable[j],查看j出现的次数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值