希尔排序

来源:互联网 发布:傲剑降龙数据 编辑:程序博客网 时间:2024/06/07 16:50

      希尔排序(Shell Sort)原理

      在这之前排序算法之前的时间复杂度都是O(n^2),希尔排序算法是突破这个时间复杂度的第一批运算之一,复杂度为O(n^(2/3))。

      直接插入排序,应该说,它的效率在某些时间是很高的,比如,我们的记录本身就是基本有序的,我们只需要少量的插入操作,就可以完成整个记录的排序工作,此时直接插入很高效。还有就是记录比较少时,直接插入的又是也比较明显。可问题是现实中记录少或者基本有序都是属于特殊情况。

      有条件当然最好,没条件我们可以去做的,于是科学家希尔研究出一种排序算法,对插入排序改进后可以增加效率。如何让待排序的记录个数少呢?很容易想到的是将原本有大量记录数的记录进行分组。分割成若干个子序列,此时每个子序列内分别进行直接插入排序,当整个序列都基本有序时,注意只是基本有序时,再对全体记录进行一次直接插入排序。

       所谓的基本有序,就是小的关键字基本在前面,大的基本在后面,不大不小的基本在中间。

       如果将现有序列{9,1,5,8,3,7,4,6,2},现在将其分为三组,{9,1,5},{8,3,7},{4,6,2},哪怕将他们各自排好序了,变成{1,5,9},{3,7,8},{2,4,6},再把他们合并成{1,5,9,3,7,8,2,4,6}。此时这个序列还是杂乱无序,谈不上基本有序。

       因此,我们需要采取跳跃分隔的思想:将相距某个“增量”的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序的。       

#include <iostream>#include <vector>using namespace std;int main(){//int a[10] = {8,9,7,6,4,2,5,3,10,1};vector<int> a;int length;cin >> length;for (int i = 0; i < length; i++)  {int number;cin >> number;a.push_back(number);  }int increment = length;while (increment!=1){increment = increment / 3 + 1;for(int i=increment;i<=length-1;i++)  {if (a[i]<a[i-increment]){swap(a[i], a[i-increment]);for (int j = i - increment; j >= 0; j = j - increment) {if(j - increment>=0&&a[j]<a[j - increment])swap(a[j], a[j - increment]); }}  } }cout << "The Shell Sort is:";vector<int>::iterator iter;for (iter = a.begin(); iter != a.end(); iter++)       {cout << *iter << " ";       }}

           

原创粉丝点击