排序算法(下)

复习任意长度的数组排序

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

所有递归都可以改写成循环
目前的minIndex

let minIndex = (numbers) => {
  numbers.indexOf(min(numbers))
let min = (numbers) => {
  return min(
    [numbers[0], min(numbers.slice(1))]
  )
}

写为循环

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

选择排序

每次找到最小的数放前面,然后对后面的数做同样的事情

let swap = (array,i,j) => {
    let temp = array[i]
    array[i] = array[j]
    array[j] = temp
}
let minIndex = (numbers) => {
    let index = 0
    for(let i=1;i<numbers.length;i++){
        if(numbers[i] < numbers[index]){
            index = i
        }
    }
    return index
}
let sort = (numbers) => {
    for(let i=0; i< numbers.length -1; i++){
        let index = minIndex(numbers.slice(i))+i  //为什么要加i,因为slice以后下标从0开始计,所以要把slice掉的下标加回来
        if(index!==i){swap(numbers, index, i)}
    }
    return numbers
}

错误地实现 swap

let swap = (a, b) => {
    let temp = a
    a = b
    b = temp
}
swap(numbers[1], numbers[2])

你会发现,numbers[1] 和 numbers[2] 的值原封不动
因为 a b 是简单类型,传参的时候会复制值
而正确的 swap 中的 numbers 是对象,传参复制地址
这是传值 V.S. 传址的区别

发现bug用console.log大法调试

let sort = (numbers) => {
    for(let i=0; i< numbers.length -1; i++){
    console.log(`----`) //这个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 quickSort = arr => {
    if (arr.length <= 1) { return arr }
    let pivotIndex = Math.floor(arr.length / 2)  //Math.floor向下取整
    let pivot = arr.splice(pivotIndex, 1)[0]  //为什么要写[0],如果不写返回的是被切掉的数组,所以提取数组中的第0个,才是我们需要的数字
    let left = []
    let right = []
    for (let i =0; i < arr.length; i++){
        if (arr[i] < pivot) { left.push(arr[i])
        } else { right.push(arr[i]) }
    }
    return quickSort(left).concat(
        [pivot], quickSort(right)
    )
}

归并排序

例如有一个数组[12, 3, 7, 21, 5, 9, 4, 6]
分成左边一半排好序,右边一半排好序
然后把左右两边合并(merge)起来
就变成了[3, 7, 12, 21]和[4, 5, 6, 9]
再分别比较两个数组的第0项,最小的提出来排前面,再把剩余的数组合并继续比较第0项

let mergeSort = arr =>{
    let k = arr.length
    if(k===1){return arr}
    let left = arr.slice(0, Math.floor(k/2))
    let right = arr.slice(Math.floor(k/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] ?
        [b[0]].concat(merge(a, b.slice(1))) : 
        [a[0]].concat(merge(a.slice(1), b))
}

计数排序

用一个哈希表作记录
发现数字 N 就记 N: 1,如果再次发现 N 就加1
最后把哈希表的 key 全部打出来,假设 N: m,那么 N 需要打印 m 次

let countSort = arr =>{
    let hashTable = {}, max = 0, result = []
    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 i =0; i<hashTable[j]; i++){
                result.push(j)
            }
        }
    }
    return result
}

其他的排序算法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容

  • Get Started • 选择排序○ 遍历○ 递归• 快速排序○ 每次取中间项,小左右大• 归并排序○ 左右两边...
    茜Akane阅读 209评论 0 0
  • 排序动图链接,自行查找。https://visualgo.net/zh/sorting 快速排序 快速排序可能是应...
    无业大学生阅读 394评论 0 0
  • 什么是算法 高德纳在《计算机程序设计艺术》里对算法的归纳:书籍推荐:《数据结构与算法分析》 输入:一个算法必须有零...
    Tuuu阅读 384评论 0 0
  • 十大经典算法排序总结对比一张图概括,主流排序算法概览: 名词解释:n: 数据规模k:“桶”的个数In-place:...
    飞菲fly阅读 630评论 0 2
  • 插入排序 借用《算法导论》里的例子,就是我们打牌的时候,每新拿一张牌都会把它按顺序插入,这,其实就是插入排序。 齐...
    码农田小齐阅读 184评论 0 0