希尔排序

排序算法----希尔排序

匿名 (未验证) 提交于 2019-12-02 23:55:01
希尔排序   希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本,该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量(gap)”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率比直接插入排序有较大提高。         1 """ 2 希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。 3 """ 4 5 6 # 方式一:元素采取直接插入排序从前往后比较 7 def shell_sort(int_list): 8 length = len(int_list) 9 if length <= 1: return int_list 10 step = length // 2 11 12 while step > 0: 13 for i in range(step, length, step): 14 item = int_list[i] 15 for j in range(0, i, step): 16 if int_list[j] > item: 17 for

希尔排序

左心房为你撑大大i 提交于 2019-12-02 21:50:19
基本思想: 先将整个待排序的记录序列分割成若干个子序列,分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录依次进行直接插入排序。   1)操作方法:选择一个增量序列t1,t2,...,tk,其中ti>tj,tk=1;   2)按增量序列个数k,对序列进行k趟排序;   3)每趟排序,根据对应的增量ti,将待排序列分割成若干个长度为m的子序列,分别对各个子序列进行直接插入排序。仅增量因子为1时,整个序列作为一个表来处理,表长度即为整个序列的长度。      代码实现: 1 private void shellSort(int[] a) { 2 int dk = a.length/2; 3 while( dk >= 1 ){ 4 ShellInsertSort(a, dk); 5 dk = dk/2; 6 } 7 } 8 private void ShellInsertSort(int[] a, int dk) { 9 //类似插入排序,只是插入排序增量是 1,这里增量是 dk,把 1 换成 dk 就可以了。 10 for(int i=dk;i<a.length;i++){ 11 if(a[i]<a[i-dk]){ 12 int j; 13 int x=a[i];//x 为待插入元素 14 a[i]=a[i-dk]; 15 for(j=i-dk; j>=0 && x

希尔排序-java实现

匿名 (未验证) 提交于 2019-12-02 21:40:30
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lixin88/article/details/91812666 是一种基于插入排序的快速的排序算法;对于大规模乱序数组插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点地从数组 的一端移动到另一端。例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确的位置就需 要 N-1 次移动。希尔排序为了加快速度简单地改进了插入排序,交换不相邻的元素以对数组的局部 进行排序,并最终用插入排序将局部有序的数组排序。 现将待排序的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,然后对各个子序列分别进行直接插入排序,待整个待排序列“基本有序”后,最后在对所有元素进行一次直接插入排序。 增量为h,则分成h个组,所有距离为h的倍数的都在一个组里,先在各组直接插入排序, 然后取第二个增量h2 重复如此;直到增量h =1; /** * 希尔排序 * O(N*(logN)^2) */ public int[] shellSort(int[] a){ if (a == null) return null; if (a.length ==1){ return a; } int inserIndex = 0; int gap = a.length/2; while (gap>0) { for

python3中的希尔排序

狂风中的少年 提交于 2019-12-02 11:54:28
def shell_sort(alist): n = len(alist) # 初始步长 gap = round(n / 2) while gap > 0: # 按步长进行插入排序 for i in range(gap, n): j = i # 插入排序 while j>=gap and alist[j-gap] > alist[j]: alist[j-gap], alist[j] = alist[j], alist[j-gap] j -= gap # 得到新的步长 gap = round(gap / 2) alist = [54,26,93,17,77,31,44,55,20,99,64] shell_sort(alist) print(alist) 来源: https://www.cnblogs.com/Gdavid/p/11743876.html

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

不想你离开。 提交于 2019-12-02 11:06:10
希尔排序: 1. 希尔排序算法描述: 希尔排序是一种缩小增量的插入排序。 2. 原理 :选取一个合适间隔gap,排数,再缩短间隔gap,排数,依次下去,直至排数完成。 例如,将一串数字5,4,2,0,7,8,1,3,9,6用希尔排序从小到大排序的步骤如下: 第一步:设置间隔为4,进行排数,得 5 ,4, 1 ,0, 7 , 6 , 2 ,3,9, 8 第二步:设置间隔为1,进行排数,得0, 1, 2, 3, 4, 5, 6, 7, 8, 9 间隔设置使用了Knuth设置,h=h*3+1。 #include<stdio.h> #include<Windows.h> using namespace std; void swap(int *arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } int main(void) { int arr[] = { 5,4,2,0,7,8,1,3,9,6 }; int len = sizeof(arr) / sizeof(int); int h = 1; while (h <= len / 3) {//设置间距 h = h * 3 + 1; } for (int gap=h ;gap > 0;gap = (gap - 1) / 3) {//缩小间距 for

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

荒凉一梦 提交于 2019-12-02 06:49:12
希尔排序其实是直接插入排序的一种优化,不过是增加了一个步长进行分组插入罢了,又称为缩小增量排序。其基本思想: 先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待gap=1时,再对全体元素进行一次直接插入排序,数组便是有序的了。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比直接插入有较大提高。 按定义直接实现: void shellsort1(int a[], int n) { int i, j, gap; for (gap = n / 2; gap > 0; gap /= 2) //步长 for (i = 0; i < gap; i++) //直接插入排序 { for (j = i + gap; j < n; j += gap) if (a[j] < a[j - gap]) { int temp = a[j]; int k = j - gap; while (k >= 0 && a[k] > temp) { a[k + gap] = a[k]; k -= gap; } a[k + gap] = temp; } } } 很明显,上面的shellsort1代码虽然对直观的理解希尔排序有帮助,但代码量太大了,不够简洁清晰。因此进行下改进和优化,以第二次排序为例

希尔排序(C++ & Python)

余生长醉 提交于 2019-12-02 06:48:07
希尔排序 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。 希尔排序实质上是一种分组插入方法。它的基本思想是:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录放在同一个组中;然后,对各组内的元素进行直接插入排序。 这一趟排序完成之后,每一个组的元素都是有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有序的。 下面以数列{80,30,60,40,20,10,50,70}为例,演示它的希尔排序过程。 第1趟:(gap=4) 当gap=4时,意味着将数列分为4个组: {80,20},{30,10},{60,50},{40,70}。 对应数列: {80,30,60,40,20,10,50,70} 对这4个组分别进行排序,排序结果: {20,80},{10,30},{50,60},{40,70}。 对应数列: {20,10,50,40,80,30,60,70} 第2趟:(gap=2) 当gap=2时,意味着将数列分为2个组:{20,50,80,60}, {10,40,30,70}。 对应数列: {20,10,50,40,80,30,60,70} 注意:{20,50

C++希尔排序

纵然是瞬间 提交于 2019-12-02 06:47:37
希尔排序的提出: 直接插入排序算法的问题: 若一个最小的值在后面,那么当排这个最小值的时候需要一步步移动,将其移动到序列的最前面,那么有没有什么方法减少这种移位? 我们不希望一步一步移动,而是给它设置一个增量让其大步移动,希尔排序由此产生,同时希尔排序打破了排序算法时间复杂度不能低于 O ( n 2 ) O ( n 2 ) //--> 。 希尔排序采用跳跃分割的策略: 将相距某个“增量”的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后的得到的结果基本有序而不是局部有序。 这里简单介绍一下基本有序的概念:小的关键字基本在前面,大的基本在后面,不大不小的基本在中间,像{2,1,,3,6,4,7,5,8,9}就可以称为基本有序,{1,5,9,3,7,8,2,4,6}就不能称为基本有序,因为最大的9在第三位,并且很小的2在导数第三位。 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 1.插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。 2.但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。 希尔排序的基本思想: 先取小于 n n //--> 的整数 d 1 d 1 //--> 作为第一个增量,把全部记录分组。所有距离为 d 1 d 1 //--> 倍数的记录放在同一组中,先在各组内进行 直接插入排序 ;然后,去第二个增量 d

希尔排序算法实现(C++)

有些话、适合烂在心里 提交于 2019-12-02 06:45:46
希尔排序是一种按照增量排序的方法。其中增量值是小于n的正整数。 shell排序的基本思想[1]是: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。 可以根据百度百科中提供的图来直观的看一下: (1)初始增量为3,该数组分为三组分别进行排序。(初始增量值原则上可以任意设置(0<gap<n),没有限制) (2)将增量改为2,该数组分为2组分别进行排序。 (3)将增量改为1,该数组整体进行排序。 下面是根据该数组实现的代码: #include <iostream> using namespace std; int a[] = {70,30,40,10,80,20,90,100,75,60,45}; void shell_sort(int a[],int n); int main() { cout<<"Before Sort: "; for(int i=0; i<11; i++) cout<<a[i]<<" "; cout<<endl; shell_sort(a, 11); cout<<"After Sort: "; for(int i=0; i

c++实现希尔排序

徘徊边缘 提交于 2019-12-02 06:45:05
希尔排序 (Shell Sort) ,也称为递减增量排序算法, 是插入排序的一种高速而稳定的改进版 本。希尔排序是基于插入排序的以下两点性质而提出改进方法的:1.插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;2.但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位。 希尔排序的一般步骤为: 1.先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中,在各组内进行直接插人排序。 2.取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。 步长的选择是希尔排序的重要部分。只要最终步长为1任何步长串行都可以工作。算法最开始以一定的步长进行排序。然后会继续以一定步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变为插入排序,这就保证了数据一定会被排序。 平均时间复杂度:O(nlogn) 稳定性:不稳定 //希尔排序是直接插入排序的改进,它的插入增量可以变化,增量为2的shell排序的时间代价可以达到θ(n的3/2次方),有的增量可以达到θ(n的7/6次方),很接近θ(n)。 //将距离某个增量的子序列分割后,分别进行直接插入排序排序。 #include <iostream> using