折半插入排序

折半插入排序也属于插入排序的一种,相较于简单插入,对查找插入位置的过程做了改进。

分析

只说明一下查找插入点的过程,其他都与直接插入一致。
分别设置变量 low,high表示有序序列的低位端和高位端下标。每次将low和high的中位值(记为mid)处的元素值与待插入值进行比较。如果较大,则令high=mid-1,否则,则令low=mid+1。 循环这个过程,直到high<low。然后把待插入值插入high后面的位置(即low所表示的位置)。 想一下如果mid处的值和待插入处的值相等怎么办,如果处理不当就会引起不稳定的情况发生,但是这是可以避免的。假如两者值相等,前面介绍的方法是会执行"否则"那条分支,即让low=mid+1,这样就把查找的范围放到了大于mid的半区,结果必然是在mid的后面,这样不会出现不稳定的情况。如果把等于的情况加在第一条分支上面,则high=mid-1,这样查找的范围就放到了小于mid的半区,结果必然实在mid的前半区,如果有相等的值,就必然会引起不稳定的情况。
查找结束的时候的,high=low-1。待插入的位置也是low所指的位置。

复杂度分析

对于时间复杂度: 外出有一个循环n-1次,内层有两种操作,一个是查找插入点,需要log2n(最大的情况)次,另外一个是移动元素,需要n(最坏情况)次。如果目标序列顺序与原顺序一样,则是最好情况,第二种移动元素的操作就会空转,不会执行,但是第一种操作是都会执行的,记作O(nlog2n)。最好情况,刚好相反,序列顺序与目标排序序列刚好相反,则第二种操作满转,注意一下,这里由于n>log2n,所以直接取n就行了,记为O(n2)
对于空间复杂度,不随排序规模增大而改变,所以是常量级别,记为O(1)

代码
void half_insert(int *array, int n)
{
	for(int i=1;i<n;++i)
	{
		int temp=array[i];
		int low=0, high=i-1;
		while(low<=high)
		{
			int m=(low+high)/2;
			if(array[m]>temp)
				high=m-1;
			else
				low=m+1;
		}
		int j=i;
		while(j>low)
		{
			array[j]=array[j-1];
			--j;
		}
		array[low]=temp;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值