排序-插入排序

来源:互联网 发布:雅思阅读 杂志 知乎 编辑:程序博客网 时间:2024/06/05 23:06

没有一种排序方法是在任何情况下都是表现最好的。

插入排序可以用一种比较易懂的方式理解是“打扑克牌”。
我们在摸牌的时候总会把之后摸的排插入到它对应的位置上去。插入排序也是一样,用一个temp存每一次“摸”进的“牌”,与已经存在的“牌”进行对比,存放到它对应的位置上去。

代码实现举例

#include<stdio.h>#define N 5void Insertion_Sort(int A[N]);                     //声明插入排序函数 int main(){    int Array[N] = {5,3,21,2,0};    Insertion_Sort(Array);    return 0;}void Insertion_Sort(int A[N]){    int i, j;    int temp;    //按照摸牌法理解,我们手中已经有一张牌,故从i=1开始排序     for( i=1; i<N; i++)                       {        temp = A[i];                          //用一个temp存储“摸”到的“牌”         for(j = i; j>0 && A[j-1]>temp; j--)   //将其与已有的“牌”一一比较,找出其对应位置             A[j] = A[j-1];                    //将已存在的一次往后挪                                      A[j] = temp;                             }    for(i = 0; i < N; i++)    {        printf("%d ",A[i]);                     //输出结果     } } 

输出结果

这里写图片描述

插入排序情况分析:
1.最好情况 顺序 T = O(N),一开始所有的数据都是顺序的,不需要进入第二层循环。
2.最坏情况 逆序 T = O(N*N),一开始所有的数据都是逆序的

插入排序的优点:
1.代码简单,简短,不需要进行多次交换。
2.能够保证数据的稳定。
<稳定性:出现两个数据相等的情况时,排序后这两个数据相对位置不变。>

时间复杂度的下界
逆序对:数组中具有性质 i < j 但A[i] > A[j]的偶(A[i], A[j])
在之前的例子中,数组为5,3,21,2,0
逆序对则是(5,3)(5,2)(5,0)(3,2)(3,0)(21,2)(21,0)(2,0),共有8对。
易知我们在进行插入排序时,一共进行了8次交换。恰好等于逆序数的对数。
其实每一次交换都是在消去逆序对,优化排序算法的关键就在于如何快速地消去多有地逆序对。
插入排序:T(N,I) = O(N+I)(I为逆序对的个数)
N个互异的数组平均逆序数是N(N-1)/4
通过交换相邻元素进行排序的任何算法平均需要Ω(N²)时间。