关于直接插入排序,在我看来它不过是对简单的选择排序进行了优化,相当于一个动态的选择排序,不过这里边的哨兵用处特别大。
void Insert_Sort(SqList* L)
{
int i, j;
for (i = 2; i <= L->length; i++)
{
if (L->Array[i] < L->Array[i - 1])
{
//需将L->Array[i]插入有序子表
L->Array[0] = L->Array[i];
//设置哨兵Array[0],用来临时存储变量
for (j = i - 1; L->Array[j] > L->Array[0]; j--)
//与哨兵位置的值进行对比,比它的值大则向后移动
L->Array[j + 1] = L->Array[j];
L->Array[j + 1] = L->Array[0]; //插入到正确位置
}
}
}
我对于这种算法理解的数组中元素变化情况如下图:
是不是有人对第三步产生了疑问?别急接下来会解释到。
第一步:
我们先将 i 位置的元素值赋值给哨兵,然后利用哨兵与第 j 个位置的元素进行对比(也就是间接的将 i 位置元素与 j 位置元素进行对比)。
第二步:
j 大于哨兵元素值或i元素值,将j位置元素赋值给原来i存储位置的值(相当于 j + 1)。此时程序运行到了
这个时候j的值是不是 i - 1(因为 i 从2开始,所以 j =1),当我们把 j 后移后 j - -,Array[j] = Array[0],不满足循环条件,此时退出该层循环。
第三步:
此时的 j - - 是不是就等于0了,也相当于哨兵位置的值,将他移动到将j原来的位置。依次遍历后边元素便能对数组进行排序了。