排序算法之三 2-路插入排序

这次要谈的插入排序算法就是2-路插入排序,2-路插入算法是在折半插入排序的基础上改进

它的目的就是想减少数据的移动次数,因此,另外开辟辅助空间。首先开辟一个长度为iLength的临时数组,将待排序数组的第1个元素放到临时数组的第0位,作为初始化。书中的意思是将该值作为每次排序的参照,大于等于这个参照值就后插,小于参照值就前插。同时定义两个游标firstfinal分别指向临时数组当前最小值和最大值所在位置。算法思路就是这样,但是在网上看了些实现好的算法,发现并不是完全按照这个思路。况且书中P262给出了排序示例,按照网上给出,完全达不到这种效果,于是本人索性就自己实现了下。当然这里还是给出两种,一种是网上找到的比较多的。闲话少说,贴代码,上图。

12-路插入排序算法实现

int TwoInsertSort()
{
	
	int final = 0;
	int first = 0;
    const int iLenght = iCount -1;

	int iTempBuff[iLenght] = {0};

	iTempBuff[0] = iRawBuff[1];
	for (int i = 2; i <= iLenght;i++)
	{
		if(iRawBuff[i] > iTempBuff[final])
		{
			//大于当前最大值,后插
			final++;
			iTempBuff[final] = iRawBuff[i];
		
		}
		if(iRawBuff[i]< iTempBuff[first])
		{
			//小于当前最小值,前插
			first = (first-1+iLenght)%iLenght;
			iTempBuff[first] = iRawBuff[i];
		
		}
		if(iRawBuff[i] < iTempBuff[final]&&iRawBuff[i] > iTempBuff[first])
		{
			//大于当前最小值,小于当前最大值,中间插
			int j = final++;
			while (iRawBuff[i] < iTempBuff[j])
			{
				iTempBuff[(j+1)%iLenght] = iTempBuff[j];
				j = (j-1+iLenght)%iLenght;
			}
            iTempBuff[j+1] = iRawBuff[i];
		
		}
		printf("第%d趟:\n",i-1);
		for(int k = 0; k < iLenght; k++)
		{
			std::cout<<iTempBuff[k]<<"\t";
		}
		std::cout<<std::endl;
	}
	//导入输入到原始数组中
	for (int k = 0; k < iLenght; k++)
	{
		iRawBuff[k+1] = iTempBuff[(first++)%iLenght];
	}
	return 0;
}

《排序算法之三 2-路插入排序》

可以看出,以这种方式进行排序的流程和书的给出的每趟排序的序列不同。主要是从插入“27”开始不同的。

下面给出本人修改后的算法(本人喜欢钻牛角尖,就是为了和书上的例子完全吻合,先不谈性能,只追求一致性)。

首先讲下思路:这里面“49”就是所谓的参照值,那么按照算法描述,每次有新的插入时候,为了实现所谓的两路,均需要和参照值进行比较。当然上面的实现也做到了两路,但是在数据的移动上有不同,就是参照值的位置有了变化。本算法的目的就是保证参照值位置不变,因此对于每个待排序的值,第一步就是和参照值进行比较,从而决定是前插还是后插。相当于划分了两个一端固定的区间。思路就是这样,本着负责的态度,上代码,贴图。

2)改进2-路插入排序算法实现

int ChangeTwoInsertSort()
{
	//ehance the two insert sort
	int final = 0;
	int first = 0;
	const int iLenght = iCount -1;

	int iTempBuff[iLenght] = {0};
	iTempBuff[0] = iRawBuff[1];
	//先和temp[0]比较从而以其为分界线
	for (int i = 2; i <= iLenght; i++ )
	{
		if (iRawBuff[i] >= iTempBuff[0])
		{
			//that means ,输入右半部
			if (iRawBuff[i] >=iTempBuff[final])
			{
				//大于当前最大值
				final++;
				iTempBuff[final] = iRawBuff[i];
			}
			else
			{
				//小于当前最大值,但大于分界线值,左移,但不超过零
				int j = final++;
				while ((iTempBuff[j]>=iRawBuff[i])&&(j>=0))
				{
					iTempBuff[j+1] = iTempBuff[j];
					j--;

				}
				iTempBuff[j+1] = iRawBuff[i];
			}

		}
		if (iRawBuff[i] < iTempBuff[0])
		{
			//that means 输入左半部
			if (iRawBuff[i] >= iTempBuff[first])
			{
				//
				int j = first--;

				while (j<=iLenght&&iTempBuff[j]<=iRawBuff[i])
				{
					iTempBuff[j-1] = iTempBuff[j];
					j++;
				}
				iTempBuff[j-1] = iRawBuff[i];
			}
			if (iRawBuff[i] < iTempBuff[first])
			{
				//小于当前最小
				first = (first-1+iLenght)%iLenght;
				iTempBuff[first] = iRawBuff[i];
			}
		}
		printf("第%d趟:\n",i);
		for(int k = 0; k < iLenght; k++)
		{
			std::cout<<iTempBuff[k]<<"\t";
		}
		std::cout<<"\n";
	
	}
	//数据导入原始数组
	for(int i = 0; i< iLenght; i++)
	{
        iRawBuff[i+1] = iTempBuff[(first++)%iLenght];
	}

	return 0;
}

《排序算法之三 2-路插入排序》

    原文作者:排序算法
    原文地址: https://blog.csdn.net/onedreamer/article/details/6745006
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞