插入排序主要包括直接插入排序和希尔排序两种,其中希尔排序是在直接插入排序的基础上改良的结果。
一. 直接插入排序
1. 直接插入排序是稳定的,它不仅适用于数组,也适用于单链表。
2. 问题描述:用直接插入排序对无序数列x进行排序。
3. 算法设计:直接插入排序基本思想是,开始时将原序列的第一个元素看作一个有序序列。然后依次取出原序列第二个元素及其后面的元素,并将其插入到有序序列中合适的位置,这样经过n-1次插入后,排序便完成。
4. 建模思想:依次进行插入即可。
5. 程序代码:
/*函数名:inst
输入参数:x 存放待排序数据的数组; n 数组长度*/
int *x;
int n;
void inst(x,n)
{
int i, j, t;
for(i = 1 ; i < n; i++){ //i表示插入次数,共进行n-1次插入
t = x[i];
for(j = i - 1; j >= 0; j--){ //寻找要插入t的位置
if(t < x[j]) x[j+1] = x[j];//后移,空出位置
else break;//找到位置,退出循环
}
x[j+1] = t;//直接插入
}
return;
}
一. 希尔排序
1. 希尔排序是不稳定的,但是它比较插入排序要快得多。
2. 问题描述:用希尔排序对无序序列x进行排序。
3. 算法设计:希尔排序又称为缩小增量排序,这是对直接排序插入排序的一种改进方法,其过程是:首先以d1(0<d1<n-1)为步长,把x中n个元素分为d1个小组,使下标距离为d1的元素在同一组中,即x[0],x[d1],x[2d1],···为一组,x[1],x[d1+1],x[2d1+1],···为第二组,而最后一组为x[d1-1],x[2d1-1],x[3d1-1],···,接着在每个组内部进行直接插入排序。然后,以d2(0<d2<d1)为步长,把x中n个元素分为d2个小组,并在每个组内进行直接插入排序。继续缩短步长,直到d=1,即把所有n个元素都看成一组,进行直接插入排序为止。随着d的减少,x中n个元素越来越有序,因而记录的比较和移动次数都比较少。
步长序列的选择方法并无定论。
4. 建模思想:
1> 设置初始步长d = n/2。
2> 对n-d个数据分别在本组内进行直接插入排序。
3> 步长减半。若d>0,则转2>继续进行插入排序,否则排序完毕,退出函数。
5. 程序代码:
/*函数名:shel
输入参数:x 存放待排序数据的数组; n 数组长度*/
int *x;
int n;
{
int i, j, d, t;
d = n/2; //初始步长是n/2
while(d>0){ //按不同步长进行排序
for(i = d; i < n; i++){ //将x[i]插入对应分组的合适位置中
t = x[i];
j = i - d;
while( (j>=0) && (x[j]>t) ){//比较和移动、
x[j+d] = t;
j = j - d;
}
x[j+d] = t; //找到了位置
}
d = d / 2; //步长减半
}
return;
}