排序之插入排序

本文介绍了两种排序算法——直接插入排序和希尔排序的基本思想、实现步骤及代码示例。直接插入排序通过逐个元素插入有序序列来实现排序,而希尔排序则是通过对数组分组并逐步减少增量的方式提高排序效率。

基本思想:每次将一个待排序的记录,按其关键字大小插入到前边已经排好序的子数组中的适当位置,知道全部记录插入完成为止。

分类:直接插入排序和希尔(shell)排序。

一、直接插入排序:

基本操作:将当前无序区的第一个记录R[i]插入到有序区R[1....i-1]中适当的位置,使得R[1...i]变为新的有序区。每次使有序区增加1个记录,也称为增量法。

可分解为以下步骤:

(1)在当前有序区R[1...i-1]中查找R[i]的正确插入位置k;

(2)将R[1...i-1]中的记录均后移以为i,腾出k位置上的空间插入R[i]。

对以上的方法进行改进,使得查找比较和记录移动操作交替进行。将待插入的记录R[i]的关键字从右向左依次与有序区中记录R[j](j=i-1,...,1’)的关键字进行比较。

采用升序排序:(1)如果R[j]的关键字大于R[i]的关键字,则将R[j]后移一位;

(2)如果R[j]的关键字小于或等于R[i]的关键字,则查找过程结束,(j+1)即为R[i]的插入位置。

这样便可完成一次直接插入排序。


使用改进方法的程序如下:

void insert_sort(int a[],int len)
{
	for(int i=1;i<len;i++)
	{
		int temp=a[i];	
		for(int j=i-1;j>=0 && a[j]>temp;j--)
			a[j+1]=a[j];
		a[j+1]=temp;
	}	
}


二、希尔排序(Shell)
基本思路:在直接插入排序中,每次只插入一个数,使有序序列只增加1个节点,并且对插入的下一个数没有提供任何帮助。希尔排序先将要排序的一组数按照某个增量d分成若干组,对每个组中的元素进行排序,然后用一个较小的增量对它进行再次分组,并对新组进行再排序。当增量减到1时,整个要排序的数被分成一个组,排序完成。所以,希尔排序其实质上也是一种分组插入的方法。

代码如下:

void shell_sort(int a[],int len)
{
	int temp;
	for(int h=len/2;h>0;h/=2)//控制增量
	{
		for(int i=h;i<len;i++)
		{
			temp=a[i];
			for(int j=i-h;j>=0&&a[j]<temp;j-=h)
			{
				a[j+h]=a[j];
			}
			a[j+h]=temp;
		}
	}
}

三、直接插入排序是一种稳定的排序方法;希尔排序是不稳定的排序方法。

希尔排序的时间性能优于直接插入排序,其原因如下:

1、当数组初始状态基本有序时,直接插入排序所需的比较和移动次数均较少。

2、当n值较小时,n和n2的差别也较小,即直接插入排序的最优时间复杂度O(n)和最坏时间复杂度O(n2)差别也不大。

3、在希尔排序开始时增量较大,分组较多,每组的记录数目少,在各组内直接插入较快,随着增量d减小,分组数逐渐减小,而各组的记录数目逐渐增多,但此时数组已较接近有序状态,所以最后一次排序也较快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

C-Jonn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值