插入排序

内部排序:排序期间元素全部存放在内存中
外部排序:排序期间元素无法全部同时放在内存中


插入排序

基本思想:每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中。
1.直接插入排序
就地排序,空间复杂度为O(1)

void InsertSort(ElemType A[], int n)
{
    int i, j;
    for(i=2;i<=n;++i)
        if(A[i].key

时间效率
最好的情况:表中元素已有序,每插入一个元素只需比较一次无序移动,O(n)
最坏的情况:表中元素逆序,总比较次数Σi,总移动次数Σ(i+1)(i属于[2,n])
平均 O(n^2)
稳定
适用性:适用于顺序存储和链式存储的线性表。适合基本有序和数据量不大的排序表。为链式存储时,可从前往后查找指定元素的位置。注:大部分排序算法都仅适用于顺序存储的线性表。

2.折半插入排序
基本思想:上一个方法是边比较边移动的,折半插入排序,先用折半查找找到插入位置,在统一移动。适用于顺序存储的线性表。

void 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].key>A[0].key)    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(nlog2n)
时间复杂度仍为O(n^2)
稳定

3.希尔排序
(缩小增量排序)
基本思想:先将待排序表分割为若干形如L[i, i+d, i+2d, ... , i+kd]的特殊子表,分别进行直接插入排序,当整个表中的元素已呈基本有序时,再对全体记录进行一次直接排序。(相隔d的元素分为一组分别进行直接插入排序,缩小d直到d为1即整体进行直接插入排序)
d1=n/2 d(i+1)=⌊di/2⌋

void ShellSort(ElemType A[], int n)
{
     for(dk=n/2;dk>=1;dk=dk/2)
        for(i=dk+1;i<=n;++i)   //前dk个分别是dk个组的第一个所以从dk+1开始排序
            if(A[i].key0&&A[0].key

空间效率O(1)
时间效率:当n在某个范围内是,O(n1.3),最坏情况O(n2)
不稳定:当相同关键字被划分到不同子表时,可能会改变相对次序。
适用性:仅适用于顺序存储的线性表

你可能感兴趣的:(插入排序)