插入排序

1. 直接插入法

    思路:将一个记录插入到已排序号的有序表中。先将序列中的第一个记录看成是一个有序的子序列,然后从第二个记录其逐个进行插入,直至整个序列变成按关键字排列的有序序列。

//pArry[i]表示当前要判定的元素,将其与其前面已排序好的所有元素相比,
//计算出该元素需要插入的位置j,后移pArry[j]至pArry[i - 1]元素
void InsertSort(int * pArry, int iLen)
{
	int i, j, k, c;
	int temp;
	for (i = 1; i < iLen; i++)   //指向当前需要判定的元素
	{
		for (j = 0; j < i; j++)  //与该元素之前的所有元素比较,找出该元素要插入的位置
		{
			if (pArry[i] < pArry[j])  //pArry[i]元素应该插在pArry[j]元素所在的位置
			{
				//保存当前要插入的值
				temp = pArry[i]; 
				//记录后移
				for (k = i, c = i - j ; c > 0; c--)
				{
					pArry[k] = pArry[k - 1];
					--k;
				}
				//插入到正确的位置
				pArry[k] = temp;
			}
		}
	}
}

     直接插入排序的时间复杂度为O(n^2)。当待排序记录的数量n很小时,这是一种很好的排序方法。但记录数量n很大时,则不宜采用直接插入排序。

2. 折半插入法

    思路:直接插入排序法中的“查找”操作可以利用“二分查找”来实现(因为前面的子序列已经是有序序列),由此进行的插入排序称之为折半插入排序。

//pArry[i]表示当前要判定的元素,将其与其前面已排序好的所有元素相比,
//计算出该元素需要插入的位置j,后移pArry[j]至pArry[i - 1]元素
void BinaryInsertSort(int * pArry, int iLen)
{
	int i, j, k, c;
	int temp;
	for (i = 1; i < iLen; i++)   //指向当前需要判定的元素
	{
		//折半查找需要插入的位置
		int low = 1;
		int high = i;
		while (low <= high)
		{
			int mid = (low + high) / 2;
			if (pArry[i] > pArry[mid - 1])
			{
				low = mid + 1;
			}
			else if (pArry[i] < pArry[mid - 1])
			{
				high = mid - 1;
			}
			else
			{
				break;
			}
		}
		j = (low + high) / 2; //找到需要插入的位置

		temp = pArry[i]; 
		//记录后移
		for (k = i, c = i - j ; c > 0; c--)
		{
			pArry[k] = pArry[k - 1];
			--k;
		}
		//插入到正确的位置, k==j
		pArry[k] = temp;
	}
}

     折半插入排序所需附加存储空间和直接插入排序相同,折半插入排序仅减少了关键字的比较次数,而记录的移动次数不变。因此其时间复杂度仍然为O(n^2)。

3. 希尔排序(缩小增量排序)

    设待排序元素序列有n个元素,首先取一个整数dk(dk < n)作为间隔, 将全部元素分为dk个子序列,所有距离为dk的元素放在同一个子序列中,然后对每一个子序列进行直接插入排序。然后缩小间隔dk,重复上述的子序列划分和排序工作。

void ShellSort(int * pArry, int ilen)
{
	int i, j;
	for (int dk = ilen / 2; dk > 0; dk /= 2)  //排序趟数, dk为间隔距离
	{
		for (i = dk; i < ilen; i++)      //对子序列进行直接插入排序
		{
			int temp = pArry[i];
			for (j = i; j >= dk && temp < pArry[j - dk]; j -= dk)
			{
				pArry[j] = pArry[j - dk];
			}
			pArry[j] = temp; 
		}
	}
}

     增量的取法有各种方案,应用不同的序列会使希尔排序的性能有很大差异,当n < 1000时,希尔排序具有很高的效率,当n很大时排序码平均比较次数和元素平均移动次数大约在n^1.25到1.6n^1.25的范围内。希尔排序算法是一种不稳定的算法。

    

   

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值