#排序算法#【2】直接插入排序、希尔排序
直接插入排序法
插入排序的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后移动,为最新元素提供插入空间。
核心代码:
//直接插入排序法 void InsertSort(int a[],int n){ int i,j,k,t; for(i = 1 ; i<n;i++){ k = a[i]; /* 第一次比较粗糙的写法 j = i-1; while(j >= 0 && a[j] > t){ a[j+1] = a[j]; j--; }*/ for(j=i-1;j>0 && a[j] >t;--j) a[j+1] = a[j]; a[j+1] = k; } }
希尔排序法
希尔排序又称为缩小增量排序,也属于插入排序类的算法,是对直接插入排序的一种改进。
基本思想就是:将需要排序的序列划分为若干个较小的序列,对这些序列进行直接插入排序,通过这样的操作可使用需要排序的数列基本有序,最后再使用一次直接插入排序。这样,首先对数量较小的序列进行直接插入排序可提高效率,最后对基本有序的序列进行直接插入排序,也可提高效率,从而使整个排序过程的效率得到提升。
刚看一遍希尔排序后,基本理解,但是理解的有偏差,应该是根据增量将数组分成若干个序列,对这些序列进行直接插入排序,但是我理解的是根据增量对每对元素进行比较大小并交换。
上图中,当增量为2时,其实是分成两个序列,然后对这两个序列进行直接插入排序,而并非只是将下标为0和2、1和3...的进行比较交换。
上代码:
//希尔排序 void ShellSort(int a[],int n){ int i,j,t,d; d = n/2; //计算第一次分量:总元素数量的一半 while(d>=1){ for(i=d;i<n;i++){ //以增量构成序列,进行直接插入排序 /* 第一次理解有误代码,可能测试数据碰巧,对有的数组排序正常 j = i+d; if(j >= n) break; if(a[i]>a[j]){ t = a[i]; a[i] = a[j]; a[j] = t; }*/ t = a[i]; //获取序列中最后一个数据 j=i-d; //获取序列中上一个序列号 //以d为增量,进行直接插入排序 while(j>=0 && a[j]>t){ a[j+d] = a[j]; j-=d; } a[j+d] = t; } d/=2; //增量减半 } }