回溯插入排序法将一个数组看成两部分,“前面”部分为有序的,“后面”部分为无序的。回溯插入法通过不断的扩展有序部
分来实现。有序部分每次从无序部分选择一个元素,将该元素附加在有序部分的后面。如果新增的元素大于有序的最后一个元
素,则扩展完成;相反,有序部分就变得有些无序了,交换这两个元素,并向前回溯一个元素,再次比较新增元素与最后的元
素,重复上面的动作,直到遇到一个比新增元素大的元素或者到达序列头。
例如,对于序列 5 8 3 6 4 1 2, 设定第一个元素是有序的。即
(5) 8 3 6 4 1 2
有序部分扩展一位
(5 8) 3 6 4 1 2
因为 5>8 显然,(5, 8) 有序
有序部分扩展一位
(5 8 3) 6 4 1 2
因 8 > 3, 交换 8和3 进行回溯 ,回溯步数为 1
((5 3) 8) 6 4 1 2
因5 > 3 交换 5 和 3,因为到达序列头,回溯完成
(3 5 8) 6 4 1 2
恢复原有未知,继续扩展一位
(3 5 8 6) 4 1 2
....
该过程循环下去,即可完成排序。
代码如下:
void insertsort(int *parr,int nmax)
{
int i;
int back = 1;
i = 0; //第一个元素为有序部分。i 指向有序部分的最后一个元素--即最大元素
while(i<nmax-1)
{
if(parr[i]>parr[i+1]) //从无序部分取得一个元素(i+1),且大于有序部分的最大元素(i)
{
int n = parr[i]; //交换
parr[i] = parr[i+1];
parr[i+1] = n;
if(i>0) //未达到元素头
{
i--; //有序部分回溯一个元素
back ++; //记录回溯的步数
continue;//开始回溯
}
}
i += back; //回溯完成,将i设置为有序部分的最后一个元素。
back = 1; //这里被用作有序部分扩展的规模
}
}