直接插入排序
直接插入排序的思想最简单也最直观
步骤:
1、查找出L(i)在[1…i-1]中的插入位置k;
2、将L[k…i-1]中所有元素依次后移一个位置;
3、将L(i)复制到L(k)
思想:每次将一个待排序的记录,按key大小插入到前面已排好序的子序列中
void Directly_InsertSort(ElemType A[], int n)
{
int i, j;
for(int i=2; i<=n; i++)
{
//依次将A[2]~A[N]插入到前面已排序的序列
if(A[i] < A[i-1])
{
//若A[i]小于前驱,将A[i]插入有序表
A[0] = A[i]; //哨兵
for(j=i-1; A[0]<A[j]; --j)
{
A[j+1] = A[j]; //向后挪位置
}
A[j+1] = A[0]; //把哨兵塞进来
}
}
}
直接插入性能分析:
空间复杂度O(1),最好时间复杂度O(1),最坏时间复杂度O(n²),支持稳定性,适用顺序存储和链式存储
折半插入排序
算法思想:先用折半查找找到应该插入的位置,再移动元素
void Half_InsertSort(ElemType A[], int n)
{
int i, j, low, high, mid;
for(i=2; i<=n; i++)
{
A[0] = A[i]; //暂存待排序的关键字
low = 1;
high = i-1;
while(low <= high)
{
mid = (low + high) / 2;
if(A[mid] > A[0])
high = mid - 1;
else
low = mid + 1;
}
for(j=i-1; j>=high+1; --j)
{
A[j+1] = A[j];
}
A[high+1] = A[0];
}
}
算法性能分析:
折半查找减少了元素的比较次数,约O(n log2(n)),比较次数与排序表初试状态无关,仅取决于表中的元素个数n;元素的移动次数未改变。时间复杂度仍是O(n²),具备稳定性