直接插入排序、希尔排序

一.直接插入排序:

原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。

最优复杂度:当输入数组就是排好序的时候,复杂度为O(n),而快速排序在这种情况下会产生O(n^2)的复杂度。
最差复杂度:当输入数组为倒序时,复杂度为O(n^2)
插入排序比较适合用于“少量元素的数组”。
直接插入排序、希尔排序_第1张图片
int* InsertSort(int a[] , int n) {
  for(int i = 1; i < n ; i++) {
    if(a[i] < a[i-1]) {
      int tmp = a[i];
      int j = i-1;
      while(j >= 0 && tmp < a[j]){
        a[j+1] = a[j];
        j--;
      }   
      a[j+1] = tmp;
    }   
  }
  return a;
}

二.希尔排序
基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
先将要排序的一组记录按某个增量dn/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至为1,最后使用直接插入排序完成排序。
/** 
  * 直接插入排序的一般形式 
  * 
  * @param int dk 缩小增量,如果是直接插入排序,dk=1 
  * 
*/
void ShellInsertSort(int* a , int n ,int dk) {
  for(int i = dk ; i < n  ;i++) {
    if(a[i] < a[i-dk]){
      int tmp = a[i];
      int j = i-dk;
      while(j >= 0 && tmp < a[j]) {
        a[j+dk] = a[j];
        j-=dk;
     }   
      a[j+dk] = tmp;
    }   
  }
}

/** 
  * 先按增量d(n/2,n为要排序数的个数进行希尔排序 
  * 
*/ 
  void ShellSort(int* a ,int n) {
    int dk = n/2;
    while(dk >=1) {
      ShellInsertSort(a , n ,dk);
      dk=dk/2;
    }
  }



你可能感兴趣的:(排序算法)