插入排序


《算法导论》第二章(算法基础)


2.1 插入排序

  • 思路分析
    我们来想象一个有趣的例子,我们得到一个任务是:
    将一副扑克牌打乱然后进行排序
    我们来分析一下大概的流程
    1.洗牌,将所有牌打乱,放置在桌子上
    2.首先从桌子上的牌顶中取得一张牌,放置在左手中
    3.以上就完成了我们的所有初始化工作
    4.现在可以进行正式的排序工作
    再从牌顶取得一张牌,拿在右手中,记住这张牌的大小
    目光聚焦在左手中,目光从右向左扫视,
    (我们这里假设左手中的牌是按照从左到右依次增大顺序排序的)
    而且我们左手中的牌就是我们最后的输出结果
    也就是说我们左手中的牌始终是排好顺序的
    而且我们设定左手中的牌从左到右依次增大
    因此就是从已经排好序的牌中的较大一端开始
    比较右手中的牌和左手中的牌
    由于第一次我们左手中只有一张牌
    因此只需要一次比较
    我们就可以确定右手中的牌应该插入到左手的牌的哪个地方
    无非就是小于在左,大于在右
    这样我们就完成了第一次排序
    下面我们继续进行分析并试图从其中总结出一些较为通用的规律
    进而提炼出我们的排序算法
    我们又取出牌顶的一张牌(注:不一定是牌顶,只不过是一种人为的规定,一种规范而已,我们总是强调风格的一致性,这也是一种风格,一旦确定这样的风格,就不要轻易地去改变,坚持下去,而且,由于我们这里桌子上的牌始终是混乱的,因此其实从这些牌中的什么位置取出一张牌用于比较,这个位置并不重要)
    注意现在我们的左手中已经有了两张牌
    和上次相同,我们的目光从右向左扫视我们的左手
    并进行比较
    然后根据比较的结果插入我们右手中的牌
    注意,这个部分是我们算法的重点
    希望大家可以静下心来
    仔细想象一下当我们真正拿着牌在排序的时候
    我们的大脑究竟是如何进行判断的
    这个过程要分析地越精细越好
    越有助于我们对程序流程和结构的剖析
    首先:
    (声明:
    严谨起见,我们将
    左手中的牌的个数记录为:j,目前j = 2
    将左手中的牌看作一个数组对象left
    使用left.length表示左手中的牌的个数也就是这个数组的长度
    也就是left[0]表示left数组的第一个变量,并以此类推
    右手中牌的大小的使用key这个变量来进行表示
    )
    我们判断的流程是:
    if (key > left[left.length - 1]){
    直接在目前左手中被比较的牌的右方插入
    也就是说在原来混乱的数组中,这两张牌其实是已经排好顺序的
    由于左手中的牌,总是拍好顺序的,因此
    当我们从桌面上拿出一张牌的时候
    如果第一次比较就发现了
    右手中的牌比左手中最右边的牌(其实也是左手中最大的牌)大
    那么就说明此刻右手中的牌比左手中任意一个都要大
    所以理所当然就应该把这张牌插入到左手牌的最右边的位置
    这里默认左手的空间足够(也就是不用移动)
    }else{
    将目光在左手中向左移动一位
    也就是关注再左边的一张牌并进行比较
    同时,将刚才比较的牌向右移动一位
    用于腾出插入的位置
    }
    现在,我们来重新审视一下我们向左手中插入一张牌的过程
    如果我们想要把这个过程在计算机中模拟的话
    我们就不得不解决这样一个问题
    就是如何来储存这些数据(即左手中的牌)
    使用数组吗?
    我们知道我们左手中的牌的数量并不固定
    如果使用一个数组的话,
    因为数组长度不能进行动态变化
    因此我们可以想到
    我们根据输入的混乱顺序的数组的长度
    向系统申请一块相同大小的长度
    这样左手(类比成一种容器,也就是类似于变量)就有了足够的容量来进行数据的储存
    这样我们就不用考虑数组长度变化的问题
    但是这样一来
    我们就浪费了内存空间
    书中的思路是这样的
    直接在原始数据的数组中进行排序
    这样的话
    就节省了大部分的内存空间
    但是有一个缺点就是我们不能回溯到原始的混乱数据
    根据我自己的理解
    书中的思路可以使用和刚才我们举的例子非常类似的一个例子来解释
    就是我们不把洗好的牌放置在桌子上
    而是直接就把它放在左手中
    然后后面的思路就几乎相同
    我们刚才的例子中
    桌面就相当于原始混乱数据
    而左手就相当于我们重新向系统申请了一块和原始数据相同大小的内存(或者说是一种可以伸缩长度的数据结构)
    然后就开始进行最开始我们讲的排序操作

  • 总结
    学习算法如果可以从生活中的例子中模拟类似的情况,是非常有助于理解算法的原理和流程的。

  • 代码实现
package chapter2;

/**
 * 插入排序算法
 * Created by 王一航 on 2016/7/1.
 */
public class InsertionSort {
    //初始化数据
    static  int[] numbers;
    //主入口
    public static void main(String[] args) {
        init();//初始化待排序数据
        show();//打印输出数据
        sort();//进行排序
        show();//打印输出数据
    }
    //初始化数组
    public static void init(){
        //将未排序的数据赋值给数组(洗牌,并将洗好的牌放置在桌子上)
        numbers = new int[]{5,2,4,6,3,6,42,66,33,87,34,11,12,10,33,12,22,32,1};
    }
    //排序算法
    public static void sort(){
        //首先从桌子上的扑克牌中取出一张,放置在左手中(这也就是为什么j = 1,而不是j = 0)
        for(int j = 1; j < numbers.length; j++){
            int key = numbers[j];//(从桌子上取出一张牌,放置在右手中)
            int i = j - 1;//眼睛盯住左手中的牌,以便于等一下进行比较
            while((i >= 0) && (numbers[i] > key)){//和左手中的牌比较大小
                numbers[i + 1] = numbers[i];
                //发现比右手中的牌大,则将其向右移动一位,以腾出插入右手中牌的空间
                //numbers[j] = numbers[i];
                i--;//将目光向左移动,以便于下一次比较
            }
            numbers[i + 1] = key;//将右手中的牌插入左手中的腾出的空闲位置
        }
    }
    //打印数组
    public static void show(){
        for(int i = 0; i < numbers.length; i++){
            System.out.print(numbers[i] + " ");
        }
    }
}

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

推荐阅读更多精彩内容