数据结构-二路插入排序

二路插入排序是对折半插入排序的改进,其目的是减少排序过程中移动记录的次数,但为此需要n个记录的辅助空间。

具体做法是:另设一个和r[]同类型的数组d,首先将r[0]赋值给d[0],并将d[0]看成是在排好序的序列中处于中间位置的记录,然后从r[]中第2个记录起依次插入到d[0]之前或之后的有序序列中。

先将待插记录的关键字和d[0]的关键字进行比较,若r[i] < d[0],则将r[i]插入到d[0]之前的有序表中。反之,则将r[i]插入到d[0]之后的有序表中。

在实现算法时,可将d看成是一个循环向量,并设两个指针first和final分别指示排序过程中得到的有序序列中的第一个记录和最后一个记录在d的位置。

其算法如下:

#include
using namespace std;

void BinInsertSort(int r[],int size)
{
    //first、final分别指示d中排好序的记录的第1个和最后1个记录的位置
    int first=0,final=0;
    int d[size]={0};
    //r中的第一个记录为d中排好序的记录
    d[0]=r[0];
    for(int i=1;i<size;++i) //依次将r的第2个~最后一个记录插入d中
    {
        if(r[i]<=d[first])  //待插入记录小于d中最小值,插入到d[first]之前(不需移动d数组的元素)
        {
            first=(first-1+size)%size;
            d[first]=r[i];
        }
        else if(r[i]>=d[final]) //待插入记录大于d中最大值,插入到d[final]之后(不需移动d数组的元素)
        {
            ++final;
            d[final]=r[i];
        }
        else    //待插入记录大于d中最小值,小于d中最大值,插入到d的中间(需要移动d数组的元素)
        {
            int j=final++;
            while(r[i]1)%size]=d[j];
                j=(j-1+size)%size;
            }
            d[(j+1)%size]=r[i];
        }
    }
    for(int i=0;i<size;++i) //循环把d赋给L
    {
        r[i]=d[(i + first) % size];
    }
}

int main()
{
    int r[]={1,23,2,15,4,-9,10,70,6,8,-4};
    BinInsertSort(r,11);
    for(int i=0;i<11;++i)
        cout<

二路插入排序中,移动记录的次数约为(n^2)/8。因此,二路插入排序只能减少移动记录的次数,而不能绝对避免移动记录。并且,当r[0]是待排序记录中关键字最小或最大的记录时,二路插入排序就完全失去它的优越性。

你可能感兴趣的:(数据结构与算法)