js排序算法详解-插入排序

来源:互联网 发布:mac guid分区方案 编辑:程序博客网 时间:2024/06/01 20:24

全栈工程师开发手册 (作者:栾鹏)

js系列教程5-数据结构和算法全解

js排序算法详解-插入排序

插入排序的原理其实很好理解,可以类比选择排序。选择排序时在两个空间进行,等于说每次从旧的空间选出最值放到新的空间,而插入排序则是在同一空间进行。

可以这么理解,在一个数组中我们不知道哪个是最小值,那么就假定第一个就是最小值,然后取第二个值与第一个值比较产排序后的序列,然后再取第三个值与排序后的序列进行比较插入到对应的位置,依次类推。

打个比方就类比水浒传一百单八将的排名吧,每个好汉来了不知道自己排老几,怎么办,那就和已经排过级别的人比较,然后找到其对应的位置,单八将宋万、杜迁先上的梁山,先默认杜迁第一来的也是单八将最厉害的,然后宋万来了,一比较宋万厉害,那宋万排第一,杜迁排第二,接下来朱贵来了,朱贵没他们两个厉害,那就排第三,再后来林冲来了,林冲比他们三个都厉害,那林冲排第一,宋万第二,杜迁第三,朱贵第四,依次类推。梁山排名其实就是典型的插入排序。

3.1插入排序

function insertionSort(array) {  console.time('插入排序耗时:');  for (var i = 1; i < array.length; i++) {    var key = array[i];    var j = i - 1;    while ( array[j] > key) {      array[j + 1] = array[j];         j--;    }    array[j + 1] = key;  }  console.timeEnd('插入排序耗时:');  return array;}var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];console.log(insertionSort(arr));

3.2升级版 二分法插入排序

function binaryInsertionSort(array) {  console.time('二分插入排序耗时:');  for (var i = 1; i < array.length; i++) {    var key = array[i], left = 0, right = i - 1;    while (left <= right) {      var middle = parseInt((left + right) / 2);      if (key < array[middle]) {        right = middle - 1;      } else {        left = middle + 1;      }    }    for (var j = i - 1; j >= left; j--) {      array[j + 1] = array[j];    }    array[left] = key;  }  console.timeEnd('二分插入排序耗时:');  return array;}var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];console.log(binaryInsertionSort(arr));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50];

二分法插入排序第一遍读下去,一脸懵逼,写的是什么鬼,仔细琢磨一下却别有一番风味,听小编慢慢讲下去,首先外层循环没什么疑问,就是简单的遍历一遍数组,那么先看while循环,left和right两个变量可以简单的类比3.1中的已排序的首末两个位置,然后选取未排序的第一个值和已排序的中间位置的值进行比较,这样的话也就是在最坏的情况下每层循环也只是计算了已排序的序列长度的一半的次数,简而言之就是在无限逼近left和right值,找到未排序第一个值应该在的位置。

还是以梁山排名为例子,在宋江没有到梁上之前,每个上梁上的人跟已经排过名的从大往小进行比较,然后找到自己的位置,在老大宋江来之后,后续人慢慢多了,然后宋老大就订了条规矩,就是每个新来的人和已排过名次的位于中间名次的好汉进行比较,胜了往前一位比较,败了往后一位比较,然后找到自己的位置。好了,while循环解释完毕,那么下面又多了一条for循环,这又是什么鬼?

不要着急,待小编与你慢慢道来,看不懂没关系,先看循环体,循环体的意思就是把前一个值给后一个,然后看循环条件是从i-1的位置从后往前依次将前一个元素的值给后一个,先不要管i-1是谁,先问 i 是谁,i 不就是未排序的第一个元素么,不就是我们拿来对已进行排序的元素么,简而言之不就是新上梁山的好汉么,那么从left值开始到 i-1 的位置依次将前一个元素的值给后一个无非就是空出 left 的位置,left 的位置不就是新上梁上好汉的位置!

插入排序法动图:

这里写图片描述

原创粉丝点击