Copyright © 1900-2016, NORYES, All Rights Reserved.

http://www.cnblogs.com/noryes/

欢迎转载,请保留此版权声明。

-----------------------------------------------------------------------------------------

希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序

基本思想:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

操作方法:

  1. 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  2. 按增量序列个数k,对序列进行k 趟排序;
  3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

希尔排序的示例:

算法实现:

我们简单处理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n为要排序数的个数

即:先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至为1,最后使用直接插入排序完成排序。

  1. void print(int a[], int n ,int i){
  2. cout<<i <<":";
  3. for(int j= 0; j<8; j++){
  4. cout<<a[j] <<" ";
  5. }
  6. cout<<endl;
  7. }
  8. /**
  9. * 直接插入排序的一般形式
  10. *
  11. * @param int dk 缩小增量,如果是直接插入排序,dk=1
  12. *
  13. */
  14. void ShellInsertSort(int a[], int n, int dk)
  15. {
  16. for(int i= dk; i<n; ++i){
  17. if(a[i] < a[i-dk]){          //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
  18. int j = i-dk;
  19. int x = a[i];           //复制为哨兵,即存储待排序元素
  20. a[i] = a[i-dk];         //首先后移一个元素
  21. while(x < a[j]){     //查找在有序表的插入位置
  22. a[j+dk] = a[j];
  23. j -= dk;             //元素后移
  24. }
  25. a[j+dk] = x;            //插入到正确位置
  26. }
  27. print(a, n,i );
  28. }
  29. }
  30. /**
  31. * 先按增量d(n/2,n为要排序数的个数进行希尔排序
  32. *
  33. */
  34. void shellSort(int a[], int n){
  35. int dk = n/2;
  36. while( dk >= 1  ){
  37. ShellInsertSort(a, n, dk);
  38. dk = dk/2;
  39. }
  40. }
  41. int main(){
  42. int a[8] = {3,1,5,7,2,4,9,6};
  43. //ShellInsertSort(a,8,1); //直接插入排序
  44. shellSort(a,8);           //希尔插入排序
  45. print(a,8,8);
  46. }
希尔排序时效分析很难,关键码的比较次数与记录移动次数依赖于增量因子序列d的选取,特定情况下可以准确估算出关键码的比较次数和记录的移动次数。目前还没有人给出选取最好的增量因子序列的方法。增量因子序列可以有各种取法,有取奇数的,也有取质数的,但需要注意:增量因子中除1 外没有公因子,且最后一个增量因子必须为1。希尔排序方法是一个不稳定的排序方法。
 /**
* Shellsort, using Shell's (poor) increments.
*/
template <class T>
void DLLALGOLIB shellSort(std::vector<T>& coll)
{
for (int gap = (int).size() / ; gap > ; gap /= )
{
for (int idx = gap; idx < (int)coll.size(); ++idx)
{
t tmp = coll[i];
int j = idx; for (; j >= gap && tmp < coll[j - gap]; j -= gap)
{
coll[j] = coll[j - gap];
} coll[j] = tmp;
}
}
}

算法系列:Shell 排序的更多相关文章

  1. 三白话经典算法系列 Shell排序实现

    山是包插入的精髓排序排序,这种方法,也被称为窄增量排序.因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元 ...

  2. Java常见排序算法之Shell排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  3. 算法篇---Shell排序(希尔)算法

    先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组内进行直接插入排序:然后,取第二个增量d2<d1重复上述的分组和排序,直至 ...

  4. 直接插入排序、折半插入排序、Shell排序、冒泡排序,选择排序

    一.直接插入排序 稳定,时间复杂度:最好O(n).最差O(n^2).平均O(n^2).空间复杂度O(1) void InsertSort(int L[], int n) { int i, j,key; ...

  5. JAVA算法系列 冒泡排序

    java算法系列之排序 手写冒泡 冒泡算是最基础的一个排序算法,简单的可以理解为,每一趟都拿i与i+1进行比较,两个for循环,时间复杂度为 O(n^2),同时本例与选择排序进行了比较,选择排序又叫直 ...

  6. JAVA算法系列 快速排序

    java算法系列之排序 手写快排 首先说一下什么是快排,比冒泡效率要高,快排的基本思路是首先找到一个基准元素,比如数组中最左边的那个位置,作为基准元素key,之后在最左边和最右边设立两个哨兵,i 和 ...

  7. 数据结构与算法系列——排序(4)_Shell希尔排序

    1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...

  8. shell排序算法

    今天看<The C Programming Language>的时候看到了shell排序算法, /* shellsort: sort v[0]...v[n-1] into increasi ...

  9. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

  10. Java排序算法(四):Shell排序

    [基本的想法] 将原本有大量记录数的记录进行分组.切割成若干个子序列,此时每一个子序列待排序的记录个数就比較少了,然后在这些子序列内分别进行直接插入排序,当整个序列都基本有序时.再对全体记录进行一次直 ...

随机推荐

  1. NX二次开发-C++time函数计时

    NX11+VS2013 #include <uf.h> #include <uf_modl.h> #include <uf_ui.h> #include <t ...

  2. Java Heap and Stack

    Heap(堆)(FIFO): heap是一个运行时数据区, 类的对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等指令建立,它们不需要程序代码来 ...

  3. hdu多校第十场 1003 (hdu6693) Valentine's Day 贪心/概率

    题意: 有许多物品,每个物品有一定概率让女朋友开心.你想让女朋友开心且只开心一次,让你挑一些物品,使得这个只开心一次的概率最大,求最大概率. 题解: 设物品i让女朋友开心的概率为$p_i$ 若你挑选了 ...

  4. hdu6110

    #include <cstdio> #include <iostream> #include <cmath> #include <cstring> #i ...

  5. 剑指offer——22表示数值的字符串

    题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3.1 ...

  6. solr +zookeeper+tomcat 集群搭建

    最近需要搭建一个cloudSolr集群,写下记录.基础环境是在centos6.5 64bit 3个下载地址: 1. 下载Solr-4.x http://lucene.apache.org/solr/d ...

  7. 5、Docker数据管理

    为了能够存储持久化数据以及共享容器间的数据,Docker提出了Volume的概念.让我们通过类似mount的方式将宿主机的文件或者目录挂载到容器中. 在容器中管理数据主要有两种方式: 数据卷(Data ...

  8. 【bug】vue同一组件使用

    vue使用同一个组件渲染,进行切换过程中会存在数据保存的情况. 比如路由切换,进行渲染的页面来自同一个组件,这个时候,要在监听路由的时候,将数据重新初始化

  9. pd.Panel转化成json,然后再还原回来

    在使用tornado的write时候有一个需求,是将panel转化成json;而接收端再将json还原成panel格式. 尝试了很久,终于实现了. panel1 =pd.Panel({"on ...

  10. Qt Creator配置

    1.安装Git sudo apt install git 2.配置Git 用户和邮箱: git config --global user.name "xxx" git config ...