三、折半插入排序

1.什么是折半插入排序

(Binary Insertion Sort)折半插入排序又称二分插入排序,是插入排序的一种。
折半插入排序是对直接插入排序的一种改进。
改进?
(直接插入排序)线性查找 —> 折半查找

​ 减少比较次数

基本思路:
每次插入操作,采用折半查找的方式,查找插入位置,

​ 然后再插入元素(先挪后插入)。

2.算法思路

step 1:找插入位置(Insertion Position)

待查找范围的下标 [low,high]
每次跟中间元素PK mid=(low+hiqh)/ 2

根据PK结果,调整待查找范围(改变low or high)

image-20210123104037173

如此重复,直到查找不成功(1ow>high了)或 查找到?

(1)查找不成功

(原有序表中没有待插入的元素)时,插入位置的确定

​ Insertion Position = high + 1 (low)

image-20210123104103657

image-20210123104624817

image-20210123105046439

(2)查找成功

(原有序表中有待插入的元素)时,插入位置的确定

靠后的插入位置,更优化(后续挪动次数会少一些)

low = mid+1,when x == a[mid]

=> 查找不成功


image-20210123105909395

image-20210123105810213

step 2:插入操作

(1)先挪元素

​ [last,—> Insertion Position]
​ high+1

(2)插入操作

x->[Insertion Position]

​ x->a[high +1]

代码实现

#include <stdio.h>
#define N 5


/*
	BinInsert:一次折半插入
	@a:有序表,数组名
	@n:有序表的元素个数
		a[0] a[1] ... a[n-1]
	@x:待插入元素
	返回值:
		无 
*/
void BinInsert(int a[], int n,int x)
{
	int i; 
	int low = 0;//查找范围,最左边元素的下标
	int high = n-1;//查找范围,最右边元素的下标
	int mid;//查找范围中间元素的下标
	
	//step 1:用二分法找插入位置
	while(low <= high)
	{
		mid = (low + high)/2;
		
		if(x >= a[mid])
		{
			low = mid + 1;
		}
		else	//x < a[mid] 
		{
			high = mid - 1;
		}
	}
	//high+1 就是x的插入位置 
	
	//step2: 插入操作(先挪后插入) 
	for(i = n - 1; i >= high+1; i--)
	{
		a[i+1] = a[i];
	}
	a[high+1] = x;
} 

void insertSort(int a[] , int n)
{
	int i,j;
	for(i = 1; i < n; i++)
	{
		BinInsert(a,i,a[i]);
	}
}


int main()
{
	int a[N]={0};
	int i;
	for(i=0;i<N;i++)
	{
		scanf("%d",&a[i]);
	}
	insertSort(a,N);
	for(i=0;i<N;i++)
	{
		printf("%d",a[i]);
	}
	printf("\n");
	return 0;
}

3.折半插入排序的性能分析

(1)时间复杂度

一次BinInsert的时间T=Ts +Tm

其中 Ts 为一次二分查找的时间

二分查找插入位置时,都是“查找不成功(查找最坏)”的情况

so,每次查找比较次数为:1og2N

​ Ts=t1*log2N

​ Tm为一次移动元素的时间
根据插入位置,每次插入移动元素的个数,分为:
最好情况:移动一个
最坏情况:移动n个
平均情况:移动(n/2)

所以,我们根据移动元素的情形,把折半插入排序的时间复杂度分为三种情况:
最好情况:

​ O(nlog2N)

image-20210123112952294

最坏情况:

​ O( n2)

image-20210123113826430

平均情况:

​ O( n2)

image-20210123113926334

(2)空间复杂度

​ O(1)

4.折半插入排序稳定性分析

折半插入排序 是 稳定的。

image-20210123134417341

5.总结

image-20210123135701205

折半插入排序相比直接插入排序只优化了查找插入位置的比较次数,移动元素的次数并没有解决。所以:
(1)当数据元素比较多(N值比较大)or
(2)移动元素的代价 小于 关键字比较时

​ 采用折半插入排序比较有优势。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Dumbking

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

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

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

打赏作者

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

抵扣说明:

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

余额充值