希尔排序

数据结构之希尔排序图文详解及代码(C++实现)

橙三吉。 提交于 2019-12-02 06:44:48
问题: 对待排序的数组r[1..n]中的元素进行直接插入排序,得到一个有序的(从小到大)的数组r[1..n]。 算法思想: 1、第一趟取增量d1(d1<n)把全部记录分为d1个组,所有间隔为d1的记录分在同一组,在各个组中进行直接插入排序。 2、第二趟取增量d2(d2<d1),重复上述的分组和排序。 3、以此类推,直到所取的增量dt=1(dt<dt_1<d_t-2<......<d2<d1),所有记录在同一组中进行直接插入排序为止。 图解: 代码: #include<iostream> using namespace std; #define MAXSIZE 20//顺序表的最大长度 typedef int KeyType;//定义关键字类型为整型 typedef int InfoType; typedef struct { KeyType key;//关键字项 InfoType otherinfo;//其他数据项 }RedType; typedef struct { RedType r[MAXSIZE+1];//r[0]闲置或做哨兵单元 int length;//顺序表的长度 }SqList;//顺序表类型 void ShellInsert(SqList &L,int dk)//对顺序表L做一趟增量是dk的希尔插入排序 { for(int i=dk+1;i<=L.length;i

排序算法系列---希尔排序(C++)

那年仲夏 提交于 2019-12-02 06:44:22
希尔排序:明白它的原理之后,希尔算法其实就是更加先进的一种插入排序,之前的直接插入排序是逐个比较,找到合适的位置就插入,希尔排序是跳跃式的插入,拿当前的数和n(自己定义的跳跃数)个之前的数比较,较小的数位置提前。希尔算法相当于先把整个序列分割成几块序列,块和块之间大小有别,块内部大小刚开始并不是有序的,随着n(自己定义的跳跃数或者增量)的减小,块内部的大小逐渐变的有序起来。其实到希尔算法进行到最后,n的值变为1(即增量或者称跳跃数变为1)的时候,它就是直接插入排序,只不过这时候,整个序列基本上是有序的,需要交换的数据已经非常少了,提高效率有一定的帮助。 增量序列的最后一个增量值必须等于1. 代码如下: # include <iostream> # define SIZE 10 using namespace std ; void ShellSort( int a[], int n) { int i,j; int jump = n; do { jump = jump/ 3 + 1 ; for (i=jump+ 1 ;i<n;i++) { if (a[i]<a[i-jump]) { a[ 0 ] = a[i]; for (j=i-jump;j> 0 &&a[ 0 ]<a[j];j-=jump) { a[j+jump] = a[j]; } a[j+jump] = a[ 0 ]; } }

C++ 希尔排序

余生颓废 提交于 2019-12-02 06:44:07
希尔排序的原理: (1)首先,从数组的首元素开始每隔“步长(间隔)”个元素就挑选一个元素出来作为子数组元素。 (2)然后每个子数组各自进行比较,比较好后,每个子数组都有顺序,进入下一轮,步长(间隔)减少, 再根据步长(间隔)分组进行比较。 (3)重复以上操作,最后就有顺序了。 #include <iostream> #include <stdlib.h> using namespace std; /*******************************************/ /* 希尔排序 /******************************************/ void ShellSort(int array[], int n) //希尔排序函数 { int i, j, step; for (step = n / 2; step > 0; step = step / 2) //这里的step步长是根据10个元素这种情况定义的 { for (i = 0; i < step; i++) //i是子数组的编号 { for (j = i + step; j < n; j = j + step) //数组下标j,数组步长下标j+step { if (array[j] < array[j - step]) { int temp = array[j]; /

排序--希尔排序

◇◆丶佛笑我妖孽 提交于 2019-12-02 00:24:59
图片转载于 https://www.cnblogs.com/chengxiao/p/6104371.html 1、什么是希尔排序? 希尔排序也是一种插入排序,他是第一个打破时间复杂度O(n^2)的排序方法,它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫 缩小增量排序 。 2、希尔排序的思想: 希尔排序是把元素按下标的一定增量进行分组,对每组使用直接插入排序算法排序; 随着增量逐渐减少,当增量减至 1 时 , 整个文件恰被分成一组,算法便终止 3、代码逐步实现: 排序的元素: int[] arr={8,9,1,7,2,3,5,4,6,0}; 3.1 交换法实现 //第一步 for (int i=5;i<arr.length;i++){ //i的初始值为初始增量 10/2=5,分为5组,每组两个元素 for (int j=i-5;j>=0;j-=5){ //j是距离i为5元素,那么,0和5一组,6和2一组,以此类推,每组比完之后,回退到上一组重新比较,具体用法看第二轮 if (arr[j+5]<arr[j]){ //比较大小,交换 temp=arr[j]; arr[j]=arr[j+5]; arr[j+5]=temp; } } } System.out.println(Arrays.toString(arr)); //第二次 for (int i=2;i<arr

希尔排序算法代码实现以及思路

妖精的绣舞 提交于 2019-12-01 18:38:05
先贴上代码 1 #include<stdio.h> 2 #define N 12 3 //length统计数组的长度 返回最后元素的下标 4 int length(int a [N]){ 5 for(int i = 0;i<=N;i++){ 6 if(a[i]==0) return i-1; 7 8 } 9 } 10 //打印输出数组元素 11 void show(int a[N]){ 12 for(int i= 0;i<N;i++){ 13 if(a[i]!=0) printf("%4d",a[i]); 14 15 } 16 } 17 //希尔排序 (插入排序升级版) 18 void shellsort(int a [N]){ 19 int gap = length(a)/2 ; 20 do{ 21 int temp=0; 22 for(int i = gap;i<=length(a);i++){ 23 for(int j = i;j>=gap;j-=gap){ 24 if(a[j-gap]>a[j]){ 25 temp = a[j-gap] ; 26 a[j-gap]=a[j] ; 27 a[j]=temp;} 28 } 29 } printf("%d\n",gap); //打印输出每次循环时gap的数值 输出值依次为为4 2 1 30 gap/=2; 31 }while

希尔排序

断了今生、忘了曾经 提交于 2019-12-01 17:22:05
希尔排序 什么是希尔排序? 希尔排序的本质就是分组插入排序 希尔排序的思想 将整个待排元素序列分割成若干个子序列 对子序列进行插入排序 依次缩减增量再次进行排序 这样往复直到整个序列元素基本有序(其实也就是增量足够小的时候) 再对整个序列进行一次直接插入排序,这次排序是在整个序列基本有序的状态,接近最好的状态 此时效果会很好 图解 注:转载自: dreamcatcher-cx博客 代码 package sort; import java.util.Arrays; public class ShellSort { public static void main(String[] args) { // TODO Auto-generated method stub int[] a= {9,8,7,6,5,4,3,2,1}; for(int k:a) { System.out.printf("%d ",k); } System.out.println(); shellSort(a); for(int k:a) { System.out.printf("%d ",k); } } public static void shellSort(int[] a) { int j,gap;//gap为增量 int n=a.length; for(gap=n/2;gap>0;gap/=2)/

从直接插入排序到希尔排序

江枫思渺然 提交于 2019-12-01 07:52:45
目录 从直接插入排序到希尔排序 希尔算法的流程 希尔算法的性能分析 Code 应试知识点 从直接插入排序到希尔排序 直接插入排序,它的原理就是把前i个长度的序列变成有序序列,然后循环迭代,直至整个序列都变为有序的。但是说来说去它还是一个时间复杂度为(n^2)的算法,难道就不能再进一步把 时间复杂度降低一阶 么? 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是 直接插入排序经过改进之后的一个更高效的版本 ,也称为缩小增量排序,同时该算法是 冲破O(n2) 的第一批算法之一。 算法思想的出发点 :(直接插入排序) 在基本有序时,效率较高 在待排序的记录个数较少时,效率较高 那么:先将 整个待排记录序列分割成若干子序列 ,分别进行直接插入排序,待 整个序列中的记录“基本有序”时 , 再对全体记录进行一次直接插入排序 。 子序列是所有距离为dk倍数的记录(下面有详细流程) 与直接插入排序相比,希尔排序多了一个划分子序列的步骤。对比直接插入排序与希尔排序的代码,可以轻松理解希尔算法实现。 希尔算法的流程 以一个具体的例子来理解整个的算法: 【初态:输入数据,dk为步长,即切片的增量】 由初态到第一趟结果的过程(从小到大排序): 【黄色:初态数据和第一趟的序列分组,红色:第一趟结果数据和第一趟序列结果数据】 由第一趟结果到第二趟结果

希尔排序,直接插入排序

一笑奈何 提交于 2019-12-01 05:00:42
希尔排序可以说是对插入排序的一种优化,时间复杂度 nlgn, public static void sort(int a[]) { for(int mid=a.length/2;mid>0;mid/=2) //mid表示增量的大小,每一次整除与2 //假如mid=1,则就是普通的直接插入排序,即从第二个元素开始对前面所有进行比较后 插入指定位置 for(int i=mid;i<a.length;i++)//分组 { int x=a[i];//准备向前插入的值 int j=i-mid; while(j>=0&&x<a[j]) //因为前面是有序的,将要插入的值跟它前面位置的比较,如果前面的小于它,那么则有序,否则跟前面不断比较,前面的值不断后移 {a[j+mid]=a[j]; j-=mid; } a[j+mid]=x; } } 来源: https://www.cnblogs.com/niliuxiaocheng/p/11656616.html

希尔排序

ぃ、小莉子 提交于 2019-11-30 23:20:19
由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新的一些复杂题目的动画,推出一个新系列 -----《图解数据结构》,主要使用动画来描述常见的数据结构和算法。本系列包括十大排序、堆、队列、树、并查集、图等等大概几十篇。 文章首发于公众号 五分钟学算法 ,欢迎关注获取更多排序内容。 推荐阅读 「算法与数据结构」从入门到进阶吐血整理推荐书单 希尔排序 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率; 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位; 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。 算法步骤 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1; 按增量序列个数 k,对序列进行 k 趟排序; 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。 来源:https://github.com

计算机基础知识——各种常用的排序算法

落花浮王杯 提交于 2019-11-30 13:33:49
稳定性 不稳定:希尔排序,直接选择,堆排序,快速排序 稳定:直接插入排序,冒泡排序,归并排序,基数排序 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。 插入排序什么时候使用高效? 小规模数据或者基本有序十分高效,数据有序程度越高,越高效 希尔排序:较大规模并且无序的数据 来源: https://www.cnblogs.com/songsongblue/p/11594559.html