第八章 排序 插入排序

插入排序

直接插入排序

void InsertSort(int r[], int n){ // r[0] 用作暂存单元和哨兵 
    int i, j;
    for(i=2; i<=n; i++){
        r[0]=r[i];
        for(j=i-1; r[0]<r[j]; j--) r[j+1]=r[j]; // 寻找插入位置 
        r[j+1]=r[0];
    }
} 
  • 最好情况 : O(n) ; 最坏情况 : O(n^2) ; 平均情况 : O(n^2)

  • 辅助存储 : O(1)

  • 是稳定排序

折半插入排序

void BInsertSort(Sqlist &L){
    int i, j; 
    for(i=2; i<=L.length; i++){
        L.r[0]=L.r[i]; // 当前插入元素存放到哨兵位置 
        low=1; high=i-1;
        while(low<=high){
            int mid=(low+high)/2;
            if(L.r[0].key<L.r[mid].key) high=mid-1;
            else low=mid+1;
        } // 循环结束 , high+1 则为插入位置
        for(j=i-1; j>=high+1; j--) L.r[j+1]=L.r[j];
        L.r[high+1]=L.r[0]; // 插入到正确位置
    }
}
  • 减少了比较次数, 但没有减少移动次数
  • 平均性能优于直接插入排序

希尔排序

void ShellSort(Sqlist &L, int dlta[], int t){
    // 按增量序列 dlta[0, t-1] 对顺序表 L 做希尔排序
    for(k=0; k<t; k++) ShellInsert(L, dlta[k]); 
} 
void ShellInsert(SqList &L, int dk){
    int i, j;
    for(i=dk+1; i<=L.length; i++){
        if(r[i].key<r[i-dk].key){
            r[0]=r[i];
            for(j=i-dk; j>0&&r[0].key<r[j].key; j=j-dk)
                r[j+dk]=r[j];
            r[j+dk]=r[0]; 
        }
    }
}
  • 时间复杂度 : O(n^{1.25}) ~ O(1.6n^{1.25}) , 约为 O(n^{1.3})
  • 算法效率与增量序列的取值有关
  • 希尔排序是一种不稳定的排序算法
  • 不适合在链式存储结构上实现

你可能感兴趣的:(数据结构-课程,算法,数据结构,排序算法)