排序算法——直接插入排序

说到排序算法,我们常用的也就7种,即:直接插入排序,希尔排序,简单选择排序,堆排序,冒泡排序,快速排序,归并排序。

下面我将依次详细地介绍这几种排序算法。 

1、直接插入排序

插入,即表示将一个新的数据插入到一个有序数组中,并继续保持有序。例如有一个长度为N的无序数组,进行N-1次的插入即能完成排序;第一次,数组第1个数认为是有序的数组,将数组第二个元素插入仅有1个有序的数组中;第二次,数组前两个元素组成有序的数组,将数组第三个元素插入由两个元素构成的有序数组中......第N-1次,数组前N-1个元素组成有序的数组,将数组的第N个元素插入由N-1个元素构成的有序数组中,则完成了整个插入排序。

基本思路:从数组的第二个元素开始,依次取数组中的元素,将它与前面的元素相比较,插入到这个元素的前面或者后面(这取决于你想从大往小排序还是从小往大排序)。然后再取下一个元素,跟前两个已经有序的数比较,插入到合适的位置。依次类推。

以下面5个无序的数据为例:65 27 59 64 58 

第1次插入: 27 65 59 64 58(先将前两个元素排序)

第2次插入: 27 59 65 64 58(将元素59插入到已经有序的数组中:27 65)

第3次插入: 27 59 64 65 58(将元素64插入到已经有序的数组中:27 59 65)

第4次插入: 27 58 59 64 65(将元素58插入到已经有序的数组中:27 59 64 65) 

算法分析

平均时间复杂度:O(n2)

空间复杂度:O(1)  (用于记录需要插入的数据)

稳定性:稳定

算法优化

插入排序中,总是先寻找插入位置,然后在实行挪动和插入过程;寻找插入位置采用顺序查找的方式(从前向后或者从后向前),既然需要插入的数组已经是有序的,那么可以采用二分查找方法来寻找插入位置,提高算法效率,但算法的时间复杂度仍为O(n2)

代码:
//插入排序算法(升序)
//pDataArray 无序数组
//iDataNum 无序数组中元素的个数
void InsertSort(int* pDataArray, int iDataNum)  
{
	int temp;
	for(int i=1;i<iDataNum;i++)//从第2个数据开始插入
	{
		int j=i-1;
		int temp=pDataArray[i];//记录要插入的数据
		//从后往前判断
		while(j>=0&&pDataArray[j]>temp)
		{
			pDataArray[j+1]=pDataArray[j];//向后移动
			j--;
		}
		if(j!=i-1)//存在比其小的数 
		{
			pDataArray[j+1]=temp;
		}		
	}
}
//二分查找插入排序
//查找数值iData在长度为iLen的pDataArray数组中的插入位置  
int FindInsertIndex(int *pDataArray, int iLen, int iData) 
{
	int ibegin=0;
	int iend=iLen-1;
	int index=-1;
	
	while(ibegin<iend)
	{
		index=(ibegin+iend)/2;
		if(pDataArray[index]>iData)
		{
			iend=index-1;
		}
		else
		{
			ibegin=index+1;
		}
	}
	if(pDataArray[index]<=iData)
		index++;
	
	return index;
}
//pDataArray 无序数组
//iDataNum 无序数组中元素的个数
void BinaryInsertSort(int* pDataArray, int iDataNum)  
{
	for(int i=1;i<iDataNum;i++)  //从第2个数据开始插入
	{
		int index=FindInsertIndex(pDataArray,i,pDataArray[i]);//二分寻找插入的位置
		if(i!=index) //插入位置不为i,才挪动,插入
		{
			int j=i;
			int temp=pDataArray[i];
			while(j>index)//移动位置
			{
				pDataArray[j]=pDataArray[j-1];
				j--;				
			}
			pDataArray[j]=temp;//插入
		}
	}
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值