Java基本排序算法 -- 直接插入排序

一、插入排序

1.1 基本思想

假设待排序的记录存放在数组r[1…n]中,任何一个待排序的记录序列初始状态可以看成是这种情况:初始时r[1]自成1个有序区,无序区为r[2…n],如图1.1所示

在这里插入图片描述

直接插入排序是一种最简单的排序方法,它的基本思想是:仅有一个记录的表,总是有序的,因此,对n个记录的表,可以从第二个记录开始直到第n个记录,逐个向有序表中进行插入操作,从而得到n个记录按关键字有序的表。

示例:使用直接插入排序数组A={16, 15, 19, 16, 18, 19, 20, 14}
将待插入记录r[i]的关键字以此与有序区中记录r[j](j=i - 1, i -2 , … 1)的关键字进行比较,若r[j]的关键字大于r[i]的关键字,则将r[j]后移一个位置;若r[j]的关键字小于或等于r[i]的关键字,则查找过程结束,j+1即为r[i]的插入位置。将r[i]插入到该位置。
在这里插入图片描述

public class InsertSort {
	/** 
	* 直接插入排序
	*/
	public void insertSort(int[] data) {
		int i, j, temp;
		for (i = 0; i < data.length - 1; i++) {
			temp = data[i + 1];
			j = i;
			while(j > -1 && temp <= data[j]) {
				data[j + 1] = data[j];
				j--;
			}
			data[j + 1] = temp;
		}
	}
}

算法的效率分析:由以上的排序过程及算法可知,其时间主要花费在关键字比较和记录的后移上。对于一个含有n个记录的序列,若初始序列即按关键字递增有序,此时在每一次排序中仅需行一次关健字的比较。这时n-1次排序总的关键字比较次数为最小值n-1次;并且在每次排序中,无须记录后移,即移动次数为0,但需要在开始时将记录移至R[0]和在最后时将记录从R[0]移回到正确位置这二次移动记录的操作,此时排序过程总的记录移动次数也为最小值2{n-1}。反之,若初始序列即按关键字递减有序,此时关键字的比较次数和记录的移动次数均取最大值,使得插入排序出现最坏的情况。对于要插入的第i个记录均要与前i-1个记录及R[0]中的关键字进行比较。每次要进行i次比较。从记录移动次数看,每次排序中除了上面所说的开始与最后两次记录移动外,还须将有序序列中所有i-1个记录均后移一个位置,此时移动记录的次数为i-1+2。从而可得到在最坏情况下字比较总次数的最大值Cmax和记录移动总次数的最大值Mmax为:
C   m a x   = ∑ i = 1 n i = ( n + 2 ) ( n + 1 ) / 2 C~max~= \sum_{i=1}^n i=(n+2)(n+1)/2 C max =i=1ni=(n+2)(n+1)/2
M   m a x   = ∑ i = 1 n ( i − 1 + 2 ) = ( n − 1 ) ( m + 4 ) / 2 M~max~=\sum_{i=1}^n(i-1+2)=(n-1)(m+4)/2 M max =i=1n(i1+2)=(n1)(m+4)/2
  因此,当初始记录序列关键字的分布情况不同时,算法在执行过程中所消耗的时间是不同的。在最好情况下,即初始序列是正序时,算法的时间复杂度为0(n);在最坏情况下,即初始序列是反序时,算法的时间复杂度为0(n2)。若初始记录序列的排列情况为随机排列,各关键字可能出现的各种排列的概率相同时,则可取最好与最坏情况的平均值,作为直接插(排序时进行关键字间的比较次数和记录移动的次数,约为n2/4,即可得直接插入排序的时间复杂度为0(n2)。
  从所需的附加空间来看,由于直接插入排序在整个排序过程中只需要一个记录单元的助空间,所以其空间复杂度为0(1),同时,从排序的稳定性来看,直接插入排序是种稳定的排序方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值