排序算法入门之「插入排序」

插入排序

借用《算法导论》里的例子,就是我们打牌的时候,每新拿一张牌都会把它按顺序插入,这,其实就是插入排序。

齐姐声明:虽然我们用打牌的例子,但是可不能学胡适先生啊。

对于数组来说怎么做呢?

有一个重要的思想,叫做挡板法,就是用挡板把数组分成两个区间:

  • 挡板左边:已排序
  • 挡板右边:未排序

那么排序分三步走:

  1. 最初挡板是在数组的最左边,index = 0 的位置,也就是保证了已排序区间里一个数都没有,或者也可以包含一个数啦;

  2. 核心思想就是:
    依次遍历未排序区间里的元素,在已排序区间里找到正确的位置插入;

  3. 重复这个过程,直到未排序区间为空。

举个例子:{5, 2, 1, 0}

第一步,挡板最初在这里:

第二步,
把 2 插入已排序区间的正确位置,变成:

重复这个步骤,把 1 排好:

最后把 0 排好:

那代码也很简单:

public void insertionSort(int[] input) {
    if (input.length <= 1) {
        return;
    }
    for(int i = 1; i < input.length; i++) {
        int tmp = input[i];
        int j = i - 1;
        while(j >= 0 && input[j] > tmp) {
            input[j+1] = input[j];
            j --;
        }
        input[j+1] = tmp;
    }
}

我们来分析一下这个算法的时空复杂度。

时间复杂度

关于时间复杂度有两个要点

  • 是描述随着自变量的增长,所需时间的增长率;
  • 是渐近线复杂度,就是说
    • 不看系数
    • 只看最高阶项

那么我们关心的 worst case 的情况就是:
如果数组是近乎倒序的,每次插入都要在数组的第一个位置插入,那么已排序区间内的所有的元素都要往后移动一位,这一步平均是 O(n),那么重复 n 次就是 O(n^2).

空间复杂度

重点是一个峰值的概念,并不是累计使用的空间。
这里是 O(1) 没什么好说的。

引入一个概念:sorted in place,也就是原地排序

原地排序就是指空间复杂度为 O(1) 的算法,因为没有占用额外的空间,就是原地打转嘛。

其实 in-place 的思想并不是只在排序算法里有,只不过排序算法是一个最广为人知的例子罢了。本质上就是一个节省使用空间的思想。

但是对于排序算法,只分析它的时空复杂度是不够的,还有另外一个重要指标:

稳定性

这个是排序算法的一个重要指标,意思是元素之间的相对顺序是否保持了不变。

比如说:{5, 2, 2, 1, 0}

这个数组排序完成后这里面的两个 2 的相对顺序没有变,那么这个排序就是一个稳定排序。

那有同学可能就想,顺序变了又有什么关系呢?

其实,在实际工作中我们排序的对象不会只是一个数字,而是一个个的对象 (object),那么先按照对象的一个性质来排序,再按照另一个性质来排序,那就不希望原来的那个顺序被改变了。好像有点抽象,我们举个例子。

比如在股票交易系统里,有买卖双方的报价,那是如何匹配的呢?

  • 先按照价格排序;
  • 在相等的价格中,按照出价的时间顺序来排序。

那么一搬来说系统会维持一个按时间排序的价格序列,那么此时只需要用一个具有稳定性的排序算法,再按照价格大小来排序就好了。因为稳定性的排序算法可以保持大小相同的两个对象仍维持着原来的时间顺序。

那么插入排序是否是稳定性的排序呢?答案是肯定的。因为在我们插入新元素的时候是从后往前检查,并不是像打牌的时候随便插一个位置不能保证相对顺序。

大家可以看下下面的动画 就非常清楚了~

优化

插入排序其实是有很大的优化空间的,你可以搜一下“希尔排序”。

在刚开始学习的时候,深度固然重要,但因为广度不够,如果学的太深可能会很痛苦,一个知识点就无穷无尽的延展,这并不是一个高效的学习方式。

所以如果时间有限,就要做好深度和广度的平衡:

  • 在常用常考的知识点上多花时间精力,追求深度;
  • 在一些拓展性的知识点上点到为止,先知道有这么回事就行。

保持 open minded 的心态,后期就会有质的提高。

如果你喜欢这篇文章,记得给我点赞留言哦~你们的支持和认可,就是我创作的最大动力,我们下篇文章见!

我是小齐,纽约程序媛,终生学习者,每天晚上 9 点,云自习室里不见不散!

更多干货文章见我的 Github: https://github.com/xiaoqi6666/NYCSDE

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