排序算法系列——直接插入排序
来源:互联网 发布:网络大电影产值 编辑:程序博客网 时间:2024/04/30 08:40
直接插入排序与希尔排序一起属于插入排序的一种。插入适合于针对小数据量进行排序,当数据量很大时插入排序的效率相对其他排序会较低,因为他的时间复杂度是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 { /** * 排序 * * @param data * 待排序的数组 */ public static <T extends Comparable<T>> void sort(T[] data) { long start = System.nanoTime(); 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; } System.out.println("use time:" + (System.nanoTime() - start) / 1000000); } public static void main(String[] args) { Random ran = new Random(); Integer[] data = new Integer[100000]; for (int i = 0; i < data.length; i++) { data[i] = ran.nextInt(10000000); } StraightInsertionSort.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)结构的复杂性及适用情况
插入排序是一种简单的排序方法,他不仅适用于顺序存储结构(数组),而且适用于链接存储结构,不过在链接存储结构上进行直接插入排序时,不用移动元素的位置,而是修改相应的指针。
- 排序算法系列——直接插入排序
- 排序算法系列——直接插入排序(C++)
- 算法—直接插入排序
- 排序算法——直接插入排序
- 排序算法——直接插入排序
- 排序算法——直接插入排序
- 排序算法—插入排序之直接插入排序
- 排序算法——插入排序(直接插入排序、折半插入排序、希尔排序)
- 【算法系列】—插入排序
- 插入排序算法 —— 直接插入排序
- 算法之插入排序——直接插入排序
- 基础算法——直接插入排序
- 排序系列--直接插入排序
- 插入排序—直接插入
- [排序算法,插入排序]--直接插入排序
- 直接插入排序算法
- 直接插入算法排序
- 直接插入排序算法
- hdu 3371 Connect the Cities(prim算法)
- mvc3.0 导出excel文件
- P2P网贷-借款与发标
- [php] Thinkphp自动验证和自动完成
- 如何在xilinx SDK中显示行号
- 排序算法系列——直接插入排序
- 64位系统下,numpy 和 Python 安装
- ubuntu中 opencv版本查看
- 粒子滤波Matlab代码
- 禁止ListView滑动
- Android UI线程和非UI线程
- Spring DAO vs Spring ORM vs Spring JDBC
- python快速入门
- 如何用python解析mnist图片