基础算法之四--排序:之希尔排序

来源:互联网 发布:无人机编程开发 教程 编辑:程序博客网 时间:2024/05/16 03:59

 

希尔排序,也称递减增量排序算法是插入排序的一种改进版本

希尔排序是基于插入排序的以下三点性质而提出改进方法的:

  • 当待排记录数n很小时, 直接插入排序效率较高
  • 当待排记录基本有序时,直接插入排序效率高, 可以达到线性排序的效率
  • 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位

 

因此,希尔排序做出了对应的改进:

        1)将整个待排记录分割成为若干子序列,分别对其进行直接插入排序

        2)待整个序列基本有序时,再对全体记录进行一次直接插入排序

 

算法原理:

        希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

        子序列不是简单的逐段分割,而是将相隔某个增量的记录组成一个子序列。 

       假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n2)的排序(冒泡排序或插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。

 

算法示例:

 

 

算法:

 

 

程序代码:

 

void ShellSort(int R[],int d[],int n,int t){// R[0].....R[n-1]  为待排数组// d[0]...d[t-1]    不能有除1之外的其他公因子// d[t-1]为1for (int i=0;i<t;i++)ShellInsert(R,n,d[i]);}void ShellInsert(int R[],int n,int d){int i,j;for (i=d;i<n;i++){if (R[i-d]>R[i]){int temp=R[i];// 待排元素temp, 以排元素 ... i-2d ,i-d,for (j=i-d;(j>=0)&&(R[j]>temp);j=j-d){R[j+d]=R[j];}R[j+d]=temp;}}}