版权声明: 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]; /*插入*/
}