算法与数据结构(五)--希尔排序
来源:互联网 发布:php调用python 编辑:程序博客网 时间:2024/06/05 07:52
希尔排序又称为“缩小增量排序”,是一种插入排序算法,是对直接插入排序的一种改进。
思想:
先按照一定的顺序跳着选元素序列进行插入排序,直到整个序列基本有序,再完整地调用一次插入排序。因为前面是跳着选元素的,就是按照一定的增量进行挑选元素,并且,这个增量是逐渐减小的,由于是跳着选的,所以,元素移动地速度就要比直接插入排序来得快,算法的时间复杂度也会明显降低。这里要注意,所取的增量序列中出了最后一个“1”以外,其他数必须是互质的,并且是按降序排列的。为什么呢?如果不是互质,就会出现都某个位置的数重复排序,这是没有必要的。
分解:
对于每一个增量n,原序列被拆分成n个序列:
(a[1] a[n+1] a[2n+1]...)
(a[2] a[n+2] a[2n+2]...)
(a[3] a[n+3] a[2n+3]...)
...
(a[n]a[2n] a[3n]...)
而上面的每一个序列的排序过程又可以拆分成依次插入排序2个、3个、4个的形式。
(a[1]a[n+1] ) (a[1]a[n+1] a[2n+1] )(a[1] a[n+1] a[2n+1] ...)
(a[2] a[n+2] ) (a[2]a[n+2] a[2n+2] ) (a[2]a[n+2] a[2n+2] ...)
(a[3] a[n+3] ) (a[3] a[n+3] a[2n+3] ) (a[3]a[n+3] a[2n+3] ...)
...
(a[n]a[2n] ) (a[n-1]a[2n-1]a[3n]) (a[n-1]a[2n-1]a[3n]...)
那么,仔细观察上述结构可以发现,上面每个序列的最后一个元素的下标按照从上到下、从左往右的顺序看,是连续的。那么,为了编程实现的方便,对于每一个n,我们都是从a[n+1]开始,一直到数组结束a[end,]找出前面与其间隔n个所有元素进行插入排序即可。这样,就可以很好的简化了整个排序过程的实现。
小插曲:
写代码的时候,一开始是打算传递整个数组进去,以int a[]作为形参,但是,发现,这样必须在返回一个数组作为返回参数。这样子的话,每执行一次,还要将返回值进行
复制到a[],会有额外的开销,所以,考虑使用数组的引用。一开始写成int &a[],一运行,报错了。查了下《C++ Primer》,下标操作比引用具有更高的优先级,所以要在前面加括号,并且必须指定数组的个数,就是写成int (&a)[11]。但是,这样写似乎太过死板了,以后代码就只能够是用于10个数的排序了。怎么办?最后,发现的利器是模板。就是将数组的元素个数以模板形式传入,这样,这个参数既是指定的,又是可以根据函数的实际调用情况来确定,真的很巧妙。
下面是代码实现:
#include <iostream>using namespace std;template<size_t N> void ShellInsert(int (&a)[N],int dk)//希尔插入排序过程{int alength = sizeof(a)/sizeof(a[0])-1;for (int i= dk+1;i<=alength;i++){if (a[i]<a[i-dk]){a[0] = a[i]; int j;for ( j=i-dk;j>0&&a[0]<a[j];j-=dk){a[j+dk] = a[j];}a[j+dk] = a[0];}}}template<size_t N> void ShellSort(int (&a)[N],int dklist[],int listlen){for (int i=0;i<listlen;i++){ShellInsert(a,dklist[i]);}}void main(){int a[] ={0,2,5,6,9,8,4,3,1,6,0};//a[0] 是哨兵int dklist[] = {5,3,1};ShellSort(a,dklist,3);for (int i = 1;i<11;i++){cout<<a[i]<<endl;}}
当然,也可以用直接传入一个指针的形式来传入参数的,就是int *a。
#include <iostream>using namespace std;void ShellInsert(int *a,int dk,int alength)//希尔插入排序过程{//int alength = 10;//sizeof(a)/sizeof(a[0])-1;for (int i= dk+1;i<=alength;i++){if (a[i]<a[i-dk]){a[0] = a[i];int j;for ( j=i-dk;j>0&&a[0]<a[j];j-=dk){a[j+dk] = a[j];}a[j+dk] = a[0];}}}void ShellSort(int *a,int alength,int dklist[],int listlen){for (int i=0;i<listlen;i++){ShellInsert(a,dklist[i],alength);}}void main(){int a[] ={0,2,5,6,9,8,4,3,1,6,0};//a[0] 是哨兵int dklist[] = {5,3,1};ShellSort(a,10,dklist,3);for (int i = 1;i<11;i++){cout<<a[i]<<endl;}}
- 算法与数据结构(五)--希尔排序
- 数据结构与算法(八)希尔排序
- 【数据结构与算法】希尔排序
- 【数据结构与算法】希尔排序
- 数据结构之排序算法(五)-直接插入排序,希尔排序,直接选择排序
- 希尔排序实现(ShellSort) Java数据结构与算法
- 数据结构与算法——希尔排序(Java实现)
- 数据结构与算法(9)---Java语言实现:希尔排序
- python数据结构与算法 33 希尔排序
- 【数据结构与算法设计】希尔排序
- 数据结构与算法简记:希尔排序
- Java数据结构与算法《八》希尔排序
- 数据结构与算法三:希尔排序
- 数据结构与算法——希尔排序
- 数据结构与算法——希尔排序
- 数据结构之希尔排序(五)
- 排序算法(五):希尔排序
- 排序算法(五) 希尔排序
- Introduction to guided filter
- 第九周项目三 输出星号图(1)
- iOS反射机制
- INTJ之ENTJ
- 易飞90设计自定义画面新增功能说明
- 算法与数据结构(五)--希尔排序
- 华为荣耀四核官方各版本大集合,速来下载哦!(不定期更新)
- 数挖开源,好像挺不错,未试过
- mac 不能识别android 手机办法
- Leetcode--Minimum Depth of Binary Tree
- tomcat unable to start within 45 seconds
- Android开发:shape和selector和layer-list的(详细说明)
- mac下安装node.js,express,webstorm9
- android自定义listview滑动删除