一、折半插入排序思路
折半插入排序又称二分插入排序。折半插入排序是通过折半查找方法现在R[0 ...i-1]中找到插入位置,在通过移动元素进行插入。折半插入和直接插入类似,只是将分散移动变为集体移动。即找到插入位置后,整体移动有序区中插入位置后的所有元素。
在R[low...high](初始时low=0,high=i-1)中通过折半查找方法找到插入位置R[high+1],在将R[high+1 ...i-1]中的元素后移一个位置。并置R[high+1]=R[i]。
二、插入算法
/***********************************************************************
* FUNCTION: 折半插入排序算法
* AUTHOR: zhuzi
* DATE: 2018-5-01
* VERSION: v1.0
* NOTES:
* MODIFICATION:
**********************************************************************/
#include <iostream>
using namespace std;
typedef int KeyType;
typedef int InfoType;
typedef struct
{
KeyType key;
InfoType data;
}RecType;
/*********************************************************************
* function: 折半插入排序
* parameters: RecType R[], 待排序数组
int n, 数组个数
* return value: 无
**********************************************************************/
void InsertSort2(RecType R[], int n)
{
int i, j, low, high, mid;
RecType tmp;
for (i = 1; i <= n; i++)
{
tmp = R[i];//无序区第一个元素
low = 0;
high = i - 1;
while(low <= high)//high + 1是合适的位置
{
mid = (low + high)/2;
if (R[mid].key > tmp.key)
{
high = mid - 1;
}
else //R[mid] <= tmp
{
low = mid + 1;
}
}
for(j = i - 1; j >= high + 1; j--)
{
R[i] = R[j];
}
R[high + 1 ] = tmp;
}
}
/*********************************************************************
* function: 输出元素
* parameters: RecType R[], 有序区数组
int n, 数组元素个数
* return value: 无
**********************************************************************/
void print(RecType R[], int n)
{
for(int i = 0; i < n ; i++)
{
cout << "R[" << i << "] <" << R[i].key << "," << R[i].data << ">" << endl;
}
}
int main(int argc, char* argv[])
{
RecType RT[] = {{1,11},{3,33},{2,22},{5,55},{7,77},{8,88}};
InsertSort2(RT, sizeof(RT)/sizeof(RT[0]));
print(RT, sizeof(RT)/sizeof(RT[0]) );
return 0;
}
三、算法分析
折半插入排序的元素移动次数与直接插入排序的移动次数相同。时间复杂度也是O(n^2)