排序高级之交换排序_梳排序

梳排序(Comb sort)是一种由Wlodzimierz Dobosiewicz于1980年所发明的不稳定排序算法,并由Stephen LaceyRichard Box于1991年四月号的Byte杂志中推广。梳排序是改良自泡沫排序快速排序,其要旨在于消除乌龟,亦即在阵列尾部的小数值,这些数值是造成泡沫排序缓慢的主因。相对地,兔子,亦即在阵列前端的大数值,不影响泡沫排序的效能。

在泡沫排序中,只比较阵列中相邻的二项,即比较的二项的间距(Gap)是1,梳排序提出此间距其实可大于1,改自插入排序希尔排序同样提出相同观点。梳排序中,开始时的间距设定为阵列长度,并在循环中以固定比率递减,通常递减率设定为1.3。在一次循环中,梳排序如同泡沫排序一样把阵列从首到尾扫描一次,比较及交换两项,不同的是两项的间距不固定于1。如果间距递减至1,梳排序假定输入阵列大致排序好,并以泡沫排序作最后检查及修正。

递减率

递减率的设定影响着梳排序的效率,原作者以随机数作实验,得到最有效递减率为1.3的。如果此比率太小,则导致一循环中有过多的比较,如果比率太大,则未能有效消除阵列中的乌龟。

亦有人提议用作递减率,同时增加换算表协助于每一循环开始时计算新间距。

变异形式

梳排序-11

设定递减率为1.3时,最后只会有三种不同的间距组合:(9, 6, 4, 3, 2, 1)、(10, 7, 5, 3, 2, 1)、或 (11, 8, 6, 4, 3, 2, 1)。实验证明,如果间距变成9或10时一律改作11,则对效率有明显改善,原因是如果间距曾经是9或10,则到间距变成1时,数值通常不是递增序列,故此要进行几次泡沫排序循环修正。加入此指定间距的变异形式称为梳排序-11(Combsort11)

混合梳排序和其他排序算法

如同快速排序合并排序,梳排序的效率在开始时最佳,接近结束时,即进入泡沫排序时最差。如果间距变得太小时(例如小于10),改用诸如插入排序鸡尾酒排序算法,则可提升整体效能。

此方法的最大好处是不再需要检查有否进行过交换程序以将排序循环提早结束。

最差时间复杂度 [1]
最优时间复杂度
平均时间复杂度
 其中p表示增量

(the number of increments)[1]

最差空间复杂度

梳排序动态图:

梳排序例子分析:

假设输入为

8 4 3 7 6 5 2 1

目标为将之变成递增排序。 因为输入长度=8,开始时设定间距为8/1.3≒6, 则比较8和2、4和1,并作交换两次。

8 4 3 7 6 5 2 1
4 3 7 6 5 8 1
2 1 3 7 6 5 8 4

第二次循环,更新间距为6/1.3≒4。比较2和6、1和5,直至7和4,此循环中只须交换一次。

2 1 3 7 6 5 8 4
2 1 3 4 6 5 8 7

接下来的每次循环,间距依次递减为3 → 2 → 1,

间距=3时,不须交换

2 1 3 4 6 5 8 7

间距=2时,不须交换

2 1 3 4 6 5 8 7

间距h=1时,交换三次

2 1 3 4 6 5 8 7
1 2 3 4 6 5 8 7
1 2 3 4 5 6 8 7
1 2 3 4 5 6 7 8

上例中,共作了六次交换以完成排序。

实现代码:

[html] view plain copy

 print?

  1. package com.baobaotao.test;  
  2. /**  
  3.  * 排序研究  
  4.  * @author benjamin(吴海旭)  
  5.  * @email benjaminwhx@sina.com / 449261417@qq.com  
  6.  *  
  7.  */  
  8. public class Sort {  
  9.       
  10.     /**  
  11.      **梳排序  
  12.      * @param array  
  13.      */  
  14.     public static void combSort(int[] array) {  
  15.         int gap = array.length ;  
  16.         boolean swapped = true ;  
  17.         while(gap > 1 || swapped) {  
  18.             if(gap > 1) {  
  19.                 gap = (int)(gap/1.3) ;  
  20.             }  
  21.             int i = 0;  
  22.             swapped = false ;  
  23.             while(i + gap < array.length) {  
  24.                 if(array[i] > array[i+gap]) {  
  25.                     swap(array, i, i+gap) ;  
  26.                     printArr(array) ;  
  27.                     swapped = true ;  
  28.                 }  
  29.                 i++ ;  
  30.             }  
  31.         }  
  32.     }  
  33.     /**  
  34.      * 按从小到大的顺序交换数组  
  35.      * @param a 传入的数组  
  36.      * @param b 传入的要交换的数b  
  37.      * @param c 传入的要交换的数c  
  38.      */  
  39.     public static void swap(int[] a, int b, int c) {  
  40.         if(b == c) return ;  
  41.         int temp = a[b] ;  
  42.         a[b] = a[c] ;  
  43.         a[c] = temp ;   
  44.     }  
  45.       
  46.     /**  
  47.      * 打印数组  
  48.      * @param array  
  49.      */  
  50.     public static void printArr(int[] array) {  
  51.         for(int c : array) {  
  52.             System.out.print(c + " ");  
  53.         }  
  54.         System.out.println();  
  55.     }  
  56.       
  57.     public static void main(String[] args) {  
  58.         int[] number={11,95,45,15,78,84,51,24,12} ;  
  59.         combSort(number) ;  
  60.     }  
  61. }  

输出分析:

[html] view plain copy

 print?

  1. 11 24 45 15 78 84 51 95 12 <span style="white-space:pre"> </span>可以看出11和51比较没变、95和24比较  
  2. 11 24 12 15 78 84 51 95 45 <span style="white-space:pre"> </span>45和12比较  
  3. 11 24 12 15 45 84 51 95 78   
  4. 11 24 12 15 45 78 51 95 84   
  5. 11 15 12 24 45 78 51 95 84   
  6. 11 12 15 24 45 78 51 95 84   
  7. 11 12 15 24 45 51 78 95 84   
  8. 11 12 15 24 45 51 78 84 95   

转载请标注:http://blog.csdn.net/benjamin_whx/article/details/42461761

时间: 2024-10-27 19:01:25

排序高级之交换排序_梳排序的相关文章

排序高级之交换排序_鸡尾酒排序

鸡尾酒排序,也就是定向冒泡排序, 鸡尾酒搅拌排序, 搅拌排序 (也可以视作选择排序的一种变形), 涟漪排序, 来回排序 or 快乐小时排序, 是冒泡排序的一种变形.此算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序. 与冒泡排序不同的地方: 鸡尾酒排序等于是冒泡排序的轻微变形.不同的地方在于从低到高然后从高到低,而冒泡排序则仅从低到高去比较序列里的每个元素.他可以得到比冒泡排序稍微好一点的效能,原因是冒泡排序只从一个方向进行比对(由低到高),每次循环只移动一个项目. 以序列(2,3,4,

排序高级之交换排序_奇偶排序

奇偶排序,或奇偶换位排序,或砖排序,是一种相对简单的排序算法,最初发明用于有本地互连的并行计算.这是与冒泡排序特点类似的一种比较排序. 该算法中,通过比较数组中相邻的(奇-偶)位置数字对,如果该奇偶对是错误的顺序(第一个大于第二个),则交换.下一步重复该操作,但针对所有的(偶-奇)位置数字对.如此交替进行下去. 处理器数组的排序 在并行计算排序中,每个处理器对应处理一个值,并仅有与左右邻居的本地互连.所有处理器可同时与邻居进行比较.交换操作,交替以奇-偶.偶-奇的顺序.该算法由Habermann

排序高级之交换排序_冒泡排序

冒泡排序(Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 冒泡排序对个项目需要O()的比较次数,且可以原地排序.尽管这个算法是最简单了解和实现的排序算法之一,但它对于少数元素之外的数列排序是很没有效率的. 冒泡排序是与插入排序拥有相等的

排序高级之交换排序_臭皮匠排序

Stooge 排序是一种低效的递归排序算法,甚至慢于冒泡排序.在<算法导论>第二版第7章(快速排序)的思考题中被提到,是由Howard.Fine等教授提出的所谓"漂亮的"排序算法. 该算法得名于三个臭皮匠,每个臭皮匠都打其他两个 实现 如果最后一个值小于第一个值,则交换这两个数 如果当前集合元素数量大于等于3: 使用臭皮匠排序前2/3的元素 使用臭皮匠排序后2/3的元素 再次使用臭皮匠排序前2/3的元素 最差时间复杂度 O(nlog 3 /log 1.5) 最差空间复杂度

排序高级之交换排序_快速排序

快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来. 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). 步骤为: 从数列中挑出一个元素,称为 "基准"(pivot

梳排序算法

梳排序(Comb sort)是一种由Wlodzimierz Dobosiewicz于1980年所发明的不稳定排序算法,并由Stephen Lacey和Richard Box于1991年四月号的Byte杂志中推广.梳排序是改良自冒泡排序和快速排序. 在冒泡排序算法中,只比较阵列中相邻的二项,即比较的二项的间距(Gap)是1,梳排序提出此间距其实可大于1,改自插入排序的希尔排序同样提出相同观点.梳排序中,开始时的间距设定为阵列长度,并在循环中以固定比率递减,通常递减率设定为1.24.在一次循环中,梳

排序算法之梳排序

排序算法之梳排序      基本思想:梳排序和希尔排序很类似.希尔排序是在直接插入排序的基础上做的优化,而梳排序是在冒泡排序的基础上做的优化.也是想希尔排序一样,将待排序序列通过增量分为若干个子序列,然后对子序列进行一趟冒泡排序,一步步减小增量,直至增量为1.所以梳排序的最后一次排序是冒泡排序.      梳排序增量是根据递减率减小的,递减率的设定影响着梳排序的效率,原作者以随机数作实验,得到最有效递减率为1.3的.      举例:待排序序列为{8, 6, 5, 2, 1, 4, 3,7}  

经典算法题每日演练——第二十四题 梳排序

这篇再看看一个经典的排序,梳排序,为什么取名为梳,可能每个梳都有自己的gap吧,大梳子gap大一点,小梳子gap小一点. 上一篇我们看到鸡尾酒排序是在冒泡排序上做了一些优化,将单向的比较变成了双向,同样这里的梳排序也是在冒泡排序上做了一些优化. 冒泡排序上我们的选择是相邻的两个数做比较,就是他们的gap为1,其实梳排序提出了不同的观点,如果将这里的gap设置为一定的大小, 效率反而必gap=1要高效的多. 下面我们看看具体思想,梳排序有这样一个1.3的比率值,每趟比较完后,都会用这个1.3去递减

java交换排序之鸡尾酒排序实现方法_java

本文实例讲述了java交换排序之鸡尾酒排序实现方法.分享给大家供大家参考.具体如下: 鸡尾酒排序,也就是定向冒泡排序, 鸡尾酒搅拌排序, 搅拌排序 (也可以视作选择排序的一种变形), 涟漪排序, 来回排序 or 快乐小时排序, 是冒泡排序的一种变形.此算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序. 与冒泡排序不同的地方: 鸡尾酒排序等于是冒泡排序的轻微变形.不同的地方在于从低到高然后从高到低,而冒泡排序则仅从低到高去比较序列里的每个元素.他可以得到比冒泡排序稍微好一点的效能,原因是冒