希尔排序

希尔排序算法

橙三吉。 提交于 2020-04-07 09:46:46
前言 当待插入元素是一个很小(当需求是从小到大排序时,从大到小排序时此处为很大)直接插入排序需要移动较多次数,性能会很差。希尔排序解决了这一问题。 基本思想 希尔排序的基本思想: 把序列按下标的一定增量分组,对每组使用直接插入排序算法排序; 随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 如果对直接插入排序不了解的朋友,可以看我的这篇文章: 详解直接插入排序算法 例子 给定数组arr为 [ 3 , 6 , 5 , 12 , 1 , 75 , 10 , -3, 0 ] 初始状态见下图: 定义变量 h 为增量,初始值为5 。 第一轮 根据增量设置成5组,颜色相同的为一组。 对每一组进行直接插入排序得到: 然后 h减半向下取整; 则 h = 3; 第二轮 根据增量设置成5组,颜色相同的为一组。 对每一组进行直接插入排序得到: 然后 h减半向下取整; 则 h = 1; 第三轮 增量为1,所有序列为一组。 插入排序后得到: h此时为1,全部有序,完毕。 由例子可知,每次都可以达到组内部分有序,大大减少了插入排序的移动开销。 代码 首先说下步长的选择: 步长的选择一般时这样的: int h = 1; while(h < arr.length / 2){ h = 2 * h + 1; } 即先把步长设置为1,只要 h 小于数组长度一半(向下取整

小蚂蚁学习数据结构(36)——插入排序中的希尔排序

匆匆过客 提交于 2020-03-21 00:02:39
3 月,跳不动了?>>> 插入排序中的第二种排序方法——希尔排序。 思路是先将要排序的序列分割成若干个子序列,分别对子序列进行直接插入排序,基本有序后,再对整个序列进行直接插入排序。 步骤:1,分割成若干子序列。2,对子序列进行直接插入排序。3,知道增量为1,进行一次全部直接插入排序即可。 希尔排序是一种不稳定排序,但是相比较直接插入排序,在时间复杂度上还是有很大程度的提升。 直接插入排序的时间复杂度是n^2,而希尔排序的时间复杂度为n^(3/2)。 # include <stdio.h> void shellSort( int * a, int n ) { int dk, j, i, t; //首先,先确定增量 dk = n/2; //增量循环递减 while( dk >= 1 ) { //内部实际上就是一个直接插入排序 for( i = dk; i < n; ++i ) { //将确定的值赋予一个中间变量 t = a[i]; //直接插入排序,但是j是按照增量递减的 for( j = i - dk; j >= 0 && t < a[j]; j-=dk ) { a[ j + dk ] = a[j]; } a[ j + dk ] = t; } --dk; } } int main( void ) { int i; int a[6] = { 55, 68, 25, 16, 89, 2

Python的希尔排序、快速排序和归并排序

本秂侑毒 提交于 2020-03-17 07:08:53
目录 一、希尔排序(Shell Sort) 二、快速排序(Quicksort) 三、归并排序 四、排序算法效率比较 五、搜索 六、二分法查找 一、希尔排序 (Shell Sort) 1、定义:是插入排序的一种,只不过间隔设为gap。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 2、原理:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。 3、希尔排序的实现: shell_sort(alist): """希尔排序法""" n = len(alist) # 初始步长 gap = n // 2 #折半设定,若n=9,则gap=4 while gap > 0: #gap=1进行最后一次循环 # 按步长进行插入排序 for j in range(gap, n):#从gap开始,控制子序列中的所有元素 i = j # 插入排序 while i > 0: if alist[i] < alist[i-gap]: alist[i-gap], alist[i] =

插入排序、希尔排序

最后都变了- 提交于 2020-03-10 06:31:07
插入排序 基本思想: 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。 void InsertSort ( vector < int > & v ) { for ( int i = 1 ; i < v . size ( ) ; i ++ ) { int k = v [ i ] ; int j ; for ( j = i - 1 ; j >= 0 ; j -- ) { if ( k < v [ j ] ) v [ j + 1 ] = v [ j ] ; else break ; } v [ j + 1 ] = k ; } } 特性总结: 元素集合越接近有序,直接插入排序算法的时间效率越高。 平均时间复杂度:O(N^2)。 空间复杂度:O(1)。 稳定性:稳定。 希尔排序 基本思想: 把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 void ShellSort ( vector < int > & v ) { int gap = v . size ( ) ; while ( 1 ) { gap = ( gap / 3 ) + 1 ; for ( int i = gap ; i < v . size ( ) ;

C++实现排序算法之希尔排序

一世执手 提交于 2020-03-05 15:36:24
C++实现排序算法之希尔排序: 时间复杂度:O(n^1.5); 算法稳定性:不稳定的排序算法; 希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因D.L.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt < dt-1 <… < d2 < d1),即所有记录放在同一组中进行直接插入排序为止。 该方法实质上是一种分组插入方法 比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时

排序之希尔排序

五迷三道 提交于 2020-02-25 23:56:00
排序是将一串数据按照其某个或者某些关键字的大小进行递增或递减排列的操作我,通常指的排序是升序,排序方式是原地排序 下面介绍下希尔排序 希尔排序 原理: 指定一个值gap,将待排序区间分成gap个组,每个组相邻元素的下标差值是gap。将每个组元素进行排序 减小gap的值,重复进行排序直到gap等于1 当gap等于1的时候,数组变成有序数组 实质: 希尔排序是对直接插入排序的优化 当gap>1时都是进行序排序,当gap=1时,数组已接近有序 希尔排序是一个不稳定的排序 实现方式 public void shellSort(int[] array) { int gap = array.length; while(gap > 1) { insertSortGap(array, gap); //gap的缩小方式决定了性能提升的程度 gap = gap / 3 + 1; } insertSortGap(array, 1); } private void insertSortGap(int[] array, int gap) { for(int i = 0; i < array.length; i++) { int tmp = array[i]; int j = i - gap; for(;j > 0 && array[j] > tmp; j -= gap) { array[j + gap] =

希尔排序

我是研究僧i 提交于 2020-02-25 19:19:44
1.希尔排序 希尔排序法又称缩小增量法。是直接排序的优化。 2.基本思想 希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成一个组,所有距离为一样的记录分在同一组内,并对每一组内的记录进行排序。然后取整数一半的值,重复上述分组和排序的工作。当值到达1时,所有记录在同一组内排好序。 3.图解 (按从小到大排序,以6个数字为例) ①将整个数组分组gap=arr.length/2;如图颜色一样的为一组。 ②将颜色一样的值进行比较,小的换到前面,大的换到后面;再进行分组gap=gap/2,如图颜色一样的为一组。 ③重复上述步骤。 ④最终排好的序列如图。 4.代码实现 public static void shellSort(int[] array) { int gap = array.length; while (gap > 1) { gap = gap / 2; insertGap(array, gap); } insertGap(array, 1); } public static void insertGap(int[] array, int gap) { for (int bound = 1; bound < array.length; bound++) { int tmp = array[bound]; int cur = bound - gap; for

希尔排序(Java)

浪子不回头ぞ 提交于 2020-02-17 01:38:35
希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。 public static void shellSort ( int [ ] arr ) { int tep = arr . length ; //增量每次减半 while ( tep / 2 > 0 ) { tep /= 2 ; for ( int i = 0 ; i < tep ; i ++ ) { //下面代码就是每组内进行插入排序 for ( int tempIndex = i + tep ; tempIndex < arr . length ; tempIndex += tep ) { int j = tempIndex ; int temp = arr [ j ] ; while ( j - tep >= 0 && temp < arr [ j - tep ] ) { arr [ j ] = arr [ j - tep ] ; j -= tep ; } arr [ j ] = temp ; } } } } 来源: CSDN 作者: 爱宝的李克用 链接: https://blog.csdn.net/weixin_45637066/article/details/104346920

java 希尔排序

独自空忆成欢 提交于 2020-02-13 02:01:43
思路 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。 希尔排序是把记录按下表的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 时间复杂度 最佳情况:T(n) = O(nlog2 n) 最坏情况:T(n) = O(nlog2 n) 平均情况:T(n) =O(nlog2n) 代码 import java.util.Arrays; /** * 希尔排序 * @author remainsu * @version 1.0 2019-06-06 */ public class ShellSort { /** * 排序方法 * @param arr 待排序的数组 * @return toString 方便输出 */ public static String shellSort(int[] arr) { //当前正在比较的数字(下方简称:“当前”) int current; //初始增量(此处为:希尔增量) int gap = arr.length / 2;

【DS】排序算法之希尔排序(Shell Sort)

让人想犯罪 __ 提交于 2020-02-13 02:00:14
一、算法思想 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 1)插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率; 2)插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位; 我们将数组中两个元素之间的距离称为Gap,相邻元素之间的Gap自然是1,很明显的,插入排序的算法在调节元素的时候,Gap是1,这就造成了上面讲的低效的原因2)。因此希尔排序的思想如下: 1)假设序列的元素个数是n,选取一个初始Gap的d(d<n); 2)将序列中元素之间距离(即Gap)为d的元素分为一组,在每组之间直接进行插入排序; 3)全部完成以后,缩小Gap至d1(d1<d),然后继续2)直到Gap为1; 常见的Gap序列如下: 1)希尔原本的Gap:N/2、N/4、...1(反复除以2) 2)Hibbard的Gap:1、3、7、...、2k-1(k表示第几个gap) 3)Knuth的Gap: 1、4、13、...、(3k - 1) / 2(k表示第几个gap) 4)Sedgewick的Gap: 1、5、19、41、109、... 二、算法示意图 如图所示,展示了分组和排序的过程。第一行是分组的过程,总共有8个元素,Gap为8/2=4,标记为相同颜色的元素为一组