经典排序算法3——插入排序

简单插入排序有两种方式,

1.可以从左到右扫描,直到遇到第一个大于等于A[i]的元素,然后就把A[i]插入到这个元素前面

2.从右到左扫描,直到遇到第一个小于等于A[i]的元素,然后就把A[i]插入到这个元素后面

这两种做法本质一样,但是一般来说用第二种,因为对于有序和基本有序的数组, 效率会更高一些,而且在插入元素的时候原则上有序表插入位置后的元素都需要移动,第一种方法在找到需要插入的位置后再进行移动,第二种可以直接在比较时候进行数据移动。还有一种做法是使用折半查找为A[i]在有序子数组中找到一个合适的位置,这种算法叫折半插入排序。

代码1

void InsertSort(int a[],int n)
{
	int i,j,k;
	for (i=1;i<n;i++)
	{
		j=0;
		while(j<=i)
		{
			if (a[j]>a[i])
			{
				break;
			}
			j++;
		}
		if (j!=i)
		{
			int temp=a[i];
			for ( k=i;k>j;k--)
			{
				a[k]=a[k-1];
			}
			a[k]=temp;
		}
		
	}
	return;

}

代码2

void InsertSort(int a[],int n)
{

	int i,j,k;
	for (i=1;i<n;i++)
	{
		j=i-1;
		while(j>=0)
		{
			if (a[j]<a[i])
			{
				break;
			}
			j--;
		}
		if (j!=i-1)
		{
			int temp=a[i];
			for ( k=i-1;k>j;k--)
			{
				a[k+1]=a[k];
			}
			a[k+1]=temp;
		}
		
	}
	return;

}

对于第二种方法,可以将比较与交换同时进行

void InsertSort(int a[],int n)
{

	for (int i=1;i<n;i++)
	{
		for (int j=i-1;j>=0&& a[j]>a[j+1];j--)
		{
			int temp = a[j];
			a[j]=a[j+1];
			a[j+1]=temp;
		}
	}
}

该算法的键值比较次数依赖于特定的输入,最坏情况下,即严格递减的数组,比较次数是:

C(n)=\sum_{i=1}^{n-1}\sum_{j=0}^{i-1}1 =\sum_{i=1}^{n-1}i =\frac{(n-1)n}{2}\in \Theta (n^{2})

因此在最坏情况下,插入和选择排序的键值比较次数是完全一致的。

在最好

情况下,即有序数组,键值的比较次数是:

C_{best}(n)=\sum_{i=1}^{n-1}1=n-1\in \Theta (n)

对于随机序列的数组,平均性能比最差性能快两倍,这使得插入排序领先于选择排序和冒泡排序。另外它还有一种扩展算法,shell排序。

猜你喜欢

转载自blog.csdn.net/zxycele/article/details/81506173
今日推荐