插入排序
简单插入排序
算法思想
将待排序的一组序列分为已排好序和未排好序的两部分;
初始状态时,已排序序列只包含第一个元素,未排序序列中的元素为此后的N-1个元素;
此后,将未排序序列中的元素逐一插入到已排序的序列中;
经过N-1次插入后,排序完成。
第k-1次插入:将未排序序列的第一个元素a从右到左依次与已排序序列中的元素b比较,如果a < b,则将a和b交换。
算法模拟
对于待排序的一组序列 44, 12, 59, 36, 43, 62
第4趟排序:此次待排元素43
第4趟排序前 | 12 | 36 | 44 | 59 | 43 | 62 |
---|---|---|---|---|---|---|
43 < 59,交换 | 12 | 36 | 44 | 43 | 59 | 62 |
43 < 44,交换 | 12 | 36 | 43 | 44 | 59 | 62 |
44 > 36,结束这一轮排序 | 12 | 36 | 43 | 44 | 59 | 62 |
算法实现
/*插入排序*/
void Insertion_sort(ElementType A[], int N)
{
ElementType tmp; /* 待插入元素值拷贝 */
for(int i = 1;i < N;i++) /* 进行N-1趟排序 */
{
tmp = A[i];
for(int j = i; j > 0 && A[j-1] > tmp;j--) /* 与已排序元素从后往前逐次比较并往后移,直到遇到小于等于它的元素 */
{
A[j] = A[j-1]; /* 将元素往后移 */
}
A[j] = tmp; /*将插入元素放入合适的位置 */
}
}
时间复杂度分析
有两个嵌套循环,每个循环进行O(N)次比较和交换,故整个算法时间复杂度为O(n2)。
稳定性分析
是稳定的。在比较时,只有当前一个元素大于后一个元素,才会进行交换。
希尔排序
算法思想
将待排序的的一组元素按一定间隔分成若干序列,每个序列进行简单插入排序。重复选取间隔进行排序,直到最后一次间隔为1,即简单插入排序。
增量序列:选取的间隔序列,用来分割待排序列。(是一个递减的序列,最后一个元素一定为1)
算法模拟
待排序的一组元素44,12,59,36,62,43,94,7,35,52,85
增量序列:5,3,1
(同一个颜色同一个序列)
排序前 | 44 | 12 | 59 | 36 | 62 | 43 | 94 | 7 | 35 | 52 | 85 |
---|---|---|---|---|---|---|---|---|---|---|---|
第一次排序(增量5) | 44 | 12 | 59 | 36 | 62 | 43 | 94 | 7 | 35 | 52 | 85 |
第一次排序结果 | 43 | 12 | 7 | 35 | 52 | 44 | 94 | 59 | 36 | 62 | 85 |
第二次排序(增量3) | 43 | 12 | 7 | 35 | 52 | 44 | 94 | 59 | 36 | 62 | 85 |
第二次排序结果 | 35 | 12 | 7 | 43 | 52 | 36 | 94 | 59 | 44 | 62 | 85 |
第三次排序(增量1) | 35 | 12 | 7 | 43 | 52 | 36 | 94 | 59 | 44 | 62 | 85 |
第三次排序结果 | 7 | 12 | 35 | 36 | 43 | 44 | 52 | 59 | 62 | 85 | 94 |
算法实现
/*希尔排序*/
void Shell_sort(ElementType A[], int N)
{
int i,p;
ElementType tmp;
int Sedgewick[] = {929, 505 , 209 , 109 , 41 , 19 , 5 , 1 , 0}; //增量序列,0用来标记排序结束
for(i = 0; Sedgewick[i]>= N;i++) // 找到初始增量序列(不超过N的最大增量)
;
for(int j = Sedgewick[i]; j > 0; j = Sedgewick[++j]) //每一个增量对应一次循环
{
for(k = j;k < N; k++)
{
tmp = A[k];
for(p = k; p >= j && A[p - j] > tmp; p -= j) //以增量j为跨度在小序列中进行插入排序
{ A[p] = A[p - j]; }
A[p] = tmp;
}
}
}
时间复杂度分析
增量序列为{
⌊
N
/
2
⌋
\lfloor N/2 \rfloor
⌊N/2⌋,
⌊
N
/
2
2
⌋
\lfloor N/ 2^2 \rfloor
⌊N/22⌋, … ,1},最差情况下时间复杂度为O(N2);
增量序列为{2k-1-1, … ,3,1},最差情况下时间复杂度为O(N3/2),平均情况下时间复杂度为O(N5/4).
稳定性分析
由于排序是在子序列中进行,所以可能发生数值相同两个元素相对位置的改变,是不稳定的。