int i,j,k;
//由小到大枚举i
for (i=1; i<n; i++) {
//寻找到插入的地址j
for (j=i-1; j>=0; j--) if (a[j]<a[ i ]) break;
if (j!=i-1) {
int temp=a[ i ];
for (k=i-1; k>j; k--)
a[k+1]=a[k];
//插入正确的位置
a[k+1]=temp;
}
}
优化1: 将寻址和插入操作合并在一个循环内。
具体操作是,判断a[ i ]与a[i-1], 若a[i-1]<a[ i ], 则前i个已然有序。 否则初始化指针j=i-1, 若a[j]>a[ j+1 ], 则往后移动一个单位, 也就是为了让a[ i ]沉下去,直到a[j]<a[j+1]则停止。代码如下:
int i,j;
for (i=1; i<n; i++)
if (a[i-1]>a[ i ])
{
int temp=a[ i ];
//大于temp的元素后移一个单位
for (j=i-1; j>=0 && a[j]>temp; j--)
a[j+1] = a[j];
a[j+1]=temp;
}
优化2: 上面代码第二个循环是为了把大于temp的元素全部往后挪, 真麻烦. 还记得冒泡排序吗? 冒泡排序是直接交换, 让a[ i ]像泡泡一样冒上去, 那这里的插入排序也用交换, 像石头一样沉下来。
最终版核心代码:
int i,j
for (i=1; i<n; i++)
for (j=i-1; j>=0 && a[j]>a[j+1]; j--)
swap(a[j],a[j+1]);