简单插入排序有两种方式,
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;
}
}
}
该算法的键值比较次数依赖于特定的输入,最坏情况下,即严格递减的数组,比较次数是:
因此在最坏情况下,插入和选择排序的键值比较次数是完全一致的。
在最好
情况下,即有序数组,键值的比较次数是:
对于随机序列的数组,平均性能比最差性能快两倍,这使得插入排序领先于选择排序和冒泡排序。另外它还有一种扩展算法,shell排序。