数据结构与算法之插入排序

  好久没写点什么了,最近很多企业都在招实习生,周围很多人也都开始到处投简历找实习了,搞的我们人心惶惶的,压力好大。尤其最近互联网好像很火的样子,作为传统通信行业的烟酒僧们,也都放弃了自己的老本行,开始投向了软开的队伍。

  只可惜我们学的是《信号与系统》、《通信原理》这种底层的理论的通信课程,虽然看起来高大上,其实也就莫过于调制解调编码解码了。虽然也是从大一就开始学C语言,但是跟计算机比起来,无论各方面都相差甚远。说多了都是泪啊!!还是拿起数据结构踏踏实实地打好基础吧!

  排序是数据结构里面很重要的一个章节,经典的排序算法主要有:

  • 插入排序:直接插入排序、折半插入排序、希尔排序
  • 交换排序:冒泡排序、快速排序
  • 选择排序:简单选择排序、堆排序
  • 归并排序
  • 基数排序

  赶紧进入主题,为什么叫插入排序?插入排序把整个待排序的序列分成有序区和无序区,初始时有序区即为待排序序列的第一个记录,然后依次将无序区中的每一个记录插入到有序区中,直到无序区为空。  

1、直接插入排序

void directInsertSort(int arr[],int n){
    int outer,inner;    
    for(outer=2; outer<=n; outer++){
        arr[0] = arr[outer];
        for(inner=outer-1; arr[inner]>arr[0]; inner--)
          arr[inner+1] = arr[inner];
        arr[inner+1] = arr[0];
    }
}
arr[0]只是作为一个待插入记录的暂存单元,下同。

2、折半插入排序

void binInsertSort(int arr[],int n){
    int outer,inner;
    int begin,end,mid;
    for(outer=2;outer<=n;outer++){
        arr[0] = arr[outer];
        begin = 1;
        end = outer-1;
        //mid = (begin+end)/2;
        while(begin <= end){
            mid = (begin+end)/2;
            if(arr[mid]>arr[0])
              end = mid-1;
            else
              begin = mid+1;
        }
        for(inner=outer-1;inner>end;inner--)
          arr[inner+1] = arr[inner];
        arr[end+1] = arr[0];
    }
}

3、希尔排序

希尔排序:先将整个待排序记录序列分割成几个子序列,在每个子序列中分别进行直接插入排序,减小增量d,重复前面的操作,直到d=1。

void shellInsertSort(int arr[],int n){
    int d;
    int outer,inner;
    for(d=n/2;d>=1;d/=2){
        for(outer=d+1;outer<=n;outer++){
            arr[0] = arr[outer];
            for(inner=outer;inner>d && arr[0]<arr[inner-d];inner-=d)
                arr[inner] = arr[inner-d];
            arr[inner] = arr[0];
        }
    }
}

改进:每个子序列可以采用折半插入排序。

4、总结

折半插入排序只是在插入记录的时候,由于是插入有序区,所以在寻找插入位置时,可以采用折半查找技术。

直接插入排序:时间复杂度ο(n2),是稳定的排序

折半插入排序:时间复杂度ο(nlog2n),稳定的排序

希尔排序:时间复杂度取决与增量的函数,不稳定的排序

原文地址:https://www.cnblogs.com/whc-uestc/p/4456201.html