数据结构知识整理 - 折半插入排序

版权声明: https://blog.csdn.net/Ha1f_Awake/article/details/85483241

折半插入排序(Binary Insertion Sort)

(可先回顾“排序算法”)

插入排序的基本思想每一趟排序中,将一个待排序记录按其关键字大小插入到“有序”记录的适当位置,直到所有待排序记录全部插入为止。

直接插入排序是最简单的排序方法,它采用顺序查找表查找待排序记录在有序序列上的插入位置,而“查找”操作可利用“折半查找”来实现,以“折半查找法”查找插入位置的排序则称为折半插入排序

<思路>

1)rcds[0]作监视哨或闲置,r[1]只有一个记录,不需要排序,所以排序从rcds[2]开始;

2)比较rcds[1]和rcds[2]的关键字大小,若rcds[1]的关键字大于rcds[2],则将rcds[1]后移一位,将首元素的位置让给rcds[2];反之,若rcds[2]的关键字更大,则保持rcds[2]原来的位置;

3)同(2)可以推理得出,若带插入记录rcds[i]的关键字大于rcds[j],小于rcds[j+1],则将rcds[j+1]到rcds[i-1]的元素后移一位,让出rcds[j+1]的位置给rcds[i];反之,若rcds[i]的关键字大于有序序列中的所有记录,则保持rcds[i]原来的位置;

4)由(3)可知,rcds[0]不仅可用作监视哨,还可以暂存待排序记录的信息。

代码如下(可回顾“折半查找”):

void Bin_Insert_Sort(SqList &L)
{
    for(int i = 2; i <= L.length; i++)    /*从rcds[2]开始插入排序*/
    {
        L.rcds[0] = L.rcds[i];            /*设置监视哨并暂存待排序记录的信息*/

        int low = 1, high = i - 1;        /*折半查找的范围是从1到i-1*/

        while(low <= high)                /*折半查找rcds[i]的插入位置*/
        {
            int mid = (low + high) / 2;

            if(L.rcds[0].key < L.rcds[mid].key) high = mid - 1;
            else low = mid + 1;
        }

        /*经过折半排序可将rcds[i]的位置确定在rcds[high+1],在草稿纸上推理一下*/

        for(int j = i-1; j >= high+1; j--) /*关键字更大的记录后移一位*/
            L.rcds[j+1] = L.rcds[j]; 

        L.rcds[high+1] = L.rcds[0];        /*插入*/
}

猜你喜欢

转载自blog.csdn.net/Ha1f_Awake/article/details/85483241