排序算法系列——直接插入排序

直接插入排序与希尔排序一起属于插入排序的一种。插入适合于针对小数据量进行排序,当数据量很大时插入排序的效率相对其他排序会较低,因为他的时间复杂度是0(n2)(下面会进行分析)。

基本思想:一组待排序的数据,首先将其划分成两部分,一部分是已排好序的,另一部分是待排序的,然后依次从待排序部分取出一个数插入到已排序部分的适当位置,保证第一部分始终是已排好序的,等待排序部分全部取出放入已排序部分之后整个排序过程就完成了。

实现要点:首先取一个关键点,将关键点前面部分作为已排好序部分,关键点后面部分作为待排序部分,通常取数组中第二数作为关键点,前面部分只有一个数所以是已排好序的,后面是待排序部分。设定关键点之后,针对待排序部分进行遍历,依次取出每个数与已排好序部分进行比较,比较时需要循环对已排好序部分的每个数进行比较,如果小于排好序部分的值则继续比较下一个,直至找到一个大于等于其的数据,将找到的数后面的每个数后移一位,然后将待排序的数插入到找到的数后面即可。

Java实现

package com.vicky.sort;

import java.util.Arrays;

/**
 1. <p>
 2. 插入排序:直接插入排序
 3.
 4. 基本思想:
 5. 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,
 6. 直至整个序列有序为止。
 7. </p>
 8.
 9. @author Vicky
 10. @date 2015-8-12
 */
public class StraightInsertionSort<T extends Comparable<T>> {
    /**
     * 排序
     *
     * @param data
     *            待排序的数组
     */
    public void sort(T[] data) {
        if (null == data) {
            throw new NullPointerException("data");
        }
        if (data.length == 1) {
            return;
        }
        // 选择起始点
        int st = 1;
        T temp;
        for (; st < data.length; st++) {
            temp = data[st];
            int j = st - 1;
            // 如果比其前一个数大,则无需移动,直接处理下一个
            if (temp.compareTo(data[j]) >= 0) {
                continue;
            }
            // 依次与已排好序部分每个数进行比较,直至找到一个比其小的数或者找到头
            for (; j >= 0 && temp.compareTo(data[j]) < 0; j--) {
                data[j + 1] = data[j];
            }
            data[j + 1] = temp;
        }
    }

    public static void main(String[] args) {
        Integer[] data = new Integer[] { 5, 312, 15, 31, 42, 11, 20, 14, 17, 9, 3, 4 };
        new StraightInsertionSort<Integer>().sort(data);
        System.out.println(Arrays.toString(data));
    }
}

代码使用了泛型,同时附带一个测试。

效率分析(引自:直接插入排序基本思想):

(1)时间复杂度

从时间分析,首先外层循环要进行n-1次插入,每次插入最少比较一次(正序),移动两次;最多比较i次,移动i+2次(逆序)(i=1,2,…,n-1)。若分别用Cmin ,Cmax 和Cave表示元素的总比较次数的最小值、最大值和平均值,用Mmin ,Mmax 和Mave表示元素的总移动次数的最小值、最大值和平均值,则上述直接插入算法对应的这些量为:

Cmin=n-1 Mmin=2(n-1)

Cmax=1+2+…+n-1=(n2-n)/2 Mmax=3+4+…+n+1=(n2+3n-4)/2

Cave=(n2+n-2)/4 Mmax=(n2+7n-8)/4

因此,直接插入排序的时间复杂度为O(n2)。

由上面对时间复杂度的分析可知,当待排序元素已从小到大排好序(正序)或接近排好序时,所用的比较次数和移动次数较少;当待排序元素已从大到小排好序(逆序)或接近排好序时,所用的比较次数和移动次数较多,所以插入排序更适合于原始数据基本有序(正序)的情况.

插入法虽然在最坏情况下复杂性为O(n2),但是对于小规模输入来说,插入排序法是一个快速的排序法。许多复杂的排序法,在规模较小的情况下,都使用插入排序法来进行排序,比如快速排序。

(2)空间复杂度

首先从空间来看,它只需要一个元素的辅助空间,用于元素的位置交换O(1)

(3)稳定性:

插入排序是稳定的,因为具有同一值的元素必然插在具有同一值得前一个元素的后面,即相对次序不变.

(4)结构的复杂性及适用情况

插入排序是一种简单的排序方法,他不仅适用于顺序存储结构(数组),而且适用于链接存储结构,不过在链接存储结构上进行直接插入排序时,不用移动元素的位置,而是修改相应的指针。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 11:28:39

排序算法系列——直接插入排序的相关文章

排序算法系列:插入排序算法

概述 直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的.记录数增1的有序表. – <大话数据结构> 版权说明 著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 本文作者:Coding-Naga 发表日期: 2016年3月24日 原文链接:http://blog.csdn.net/lemon_tree12138/article/details/50968422 来源:CSDN 更多内容:分类 &

排序算法系列之插入排序 (1)

排序,即是以一定的规则组织数据,排序算法的优劣关键在于比较数据的交换和移动次数. 排序算法需要考虑的几点:数据交换次数,移动次数,数据越界,算法的实用性(符合多种类型) //预知:使用C#拓展方法进行数据输出,使用StringBuilder节约内存开销 public static class DebugExtension { public static void DebugArray<T>(T[] array) { StringBuilder sb = new StringBuilder(ar

排序算法系列——插入排序

记录学习点滴,菜鸟成长记 接触算法是研究生期间做项目时,需要编写一些诸如GA.QGA的时候,第一次使用“排序”还是用的Java自带的Comparator接口.后来买了<算法导论>来看,发现果然所有知识都是有专业壁垒的,简单的一个问题尽然蕴藏着如此多的思想,发现此简直欣喜无比,遂决定要好好研究研究.只有深入后才发现,原来算法的不仅仅是按照逻辑顺序写个程序那么简单,好的算法要考虑到方方面面,最简单的时间复杂度就够我学习很长时间了. 将自己学习排序算法的一些理解和感悟记录于此,方便自己温故而知新.

排序算法系列——堆排序

记录学习点滴,菜鸟成长记 堆排序引入了另一种算法设计技巧:使用一种我们称之为“堆”的数据结构来进行数据管理. 堆排序算是真正意义上的利用数据结构来求解数组排序的方法. “插入排序”和“归并排序”可以看做是一种“计算机体力活”,体现的思想更多的是去模拟最简单的人类思维,比如插入排序过程中的比较,归并中子问题合并时的比较. “堆排序”可以看做是“计算机脑力活”,他利用了一种结构化的语言来表达,这种结构化带来一些性质,比如左右孩子.比[堆大小的一半向下取整]大的下标都是叶节点不需要维护其最大堆性质等.

(转载)排序算法系列

排序算法系列 目录 概述 概念 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列. 排序分为内部排序和外部排序. 若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序. 反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序. 排序分类 如果按照策略来分类,大致可分为:交换排序.插入排序.选择排序.归并排序和基数排序.如 图-排序策略分类图 所示. 图-排序策略分类图 算

排序算法系列——归并排序

记录学习点滴,菜鸟成长记 归并排序的英文叫做Merge-Sort,要想明白归并排序算法,还要从“递归”的概念谈起. 1.递归 一般来讲,人在做决策行事的时候是往往是从已知出发,比如,我又要举个不恰当的例子了→_→: 看到漂亮姑娘→喜欢人家→追→女朋友→老婆 但是人家施瓦辛格不是这么想的,人家从小就立志当总统: 要当总统←先当州长←竞选州长要有钱←那得找个有钱妹子←妹子都喜欢明星←身材好能当明星←健身 递归,就像一个人对自己的发展有清晰的规划和坚定的信心一样,他知道每一步会有怎么样的结果,他需要仅

排序算法之 Java插入排序算法

package net.qh.test.sort; import java.util.ArrayList; import java.util.Calendar; import java.util.List; /** * Created by Administrator on 2016/03/01. */ public class Insert { public int[] sort(int[] arr){ if ( arr == null || arr.length <= 1 ){ return

排序算法系列——快速排序

记录学习点滴 快速排序算法是一种很有趣的算法,短小精悍,性能强劲,对于大部分情况都可以胜任,但对极端环境难以应付. 快速排序我理解为:这是一个“以自我为中心的”+“分治法”思想的算法. 分治法不必多说,化繁为简,那就是逐个击破. 那什么是“以自我为中心”?顾名思义,就是每次都一个“我”,每个人都要围绕“我”行事,比“我”小的都去左边站着,比“我”他大的都去右边站着,而且“我”不去关心每一边都有谁,反正你没“我”大或者小就行.一旦“我”落位了妥帖了,“我”就不动了.然后再在左右两边分别产生新“我”

七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)

 写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列.因此排序掌握各种排序算法非常重要.对下面介绍的各个排序,我们假定所有排序的关键字都是整数.对传入函数的参数默认是已经检查好了的.只是简单的描述各个算法并给出了具体实现代码,并未做其他深究探讨. 基础知识: 由于待排序的记录数量不同,使得排序过程中设计的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在计算机随机存储器中进行的排序过程.另一类是外部排序,