回溯插入排序法

来源:互联网 发布:lua调用java方法 编辑:程序博客网 时间:2024/04/29 04:37

回溯插入排序法将一个数组看成两部分,“前面”部分为有序的,“后面”部分为无序的。回溯插入法通过不断的扩展有序部

分来实现。有序部分每次从无序部分选择一个元素,将该元素附加在有序部分的后面。如果新增的元素大于有序的最后一个元

素,则扩展完成;相反,有序部分就变得有些无序了,交换这两个元素,并向前回溯一个元素,再次比较新增元素与最后的元

素,重复上面的动作,直到遇到一个比新增元素大的元素或者到达序列头。
例如,对于序列  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; //这里被用作有序部分扩展的规模
        }      
}