梳排序(CombSort)思想与实现

  梳排序也属于简单的排序算法,也是一种不稳定的排序方法。在讲述梳排序的思想之前,先介绍一下与该排序有关的一个关键常量:递减率;该常量为固定值:1.3。该常量是由原作者Wlodzimierz Dobosiewicz以随机数做实验得到的,对于此大可不必纠结,直接用就行。

(1) 梳排序的思想

  梳排序的思想就是:最开始的时候先定义一个步长,该步长为数组的长度除以1.3(注意:直接用整型除即可,例如数组长度为5,则开始的步长为5/1.3=3),然后从第0个元素开始,跟距离当前元素为步长大小的元素进行比较(例如,开始步长为3,所以第0个元素跟第3个元素进行比较),若前者大于后者就进行交换,否则继续往后进行比较,直到比较到最后一个元素为止;完成前面的操作后,第一步就算完成了,接下来从第二步开始,将第一步的步长除以1.3(第一步的例子中步长为3,故第二步的步长为3/1.3=2)后得到新的步长,之后参照第一步的做法进行比较,直到比较到最后一个元素为止;接下来讲述一下约束条件,当步长小于1的时候,不再进行比较操作。此外,稍微提一下,该例子以排升序为例,排降序与其类似,读者参照后可自行编写。

  所以,从上述的思想中,我们知道:递减率其实就是所要比较的两个元素的间距的递减率为了更好地理解该算法的思想,我们来看以下图片:


从上图可以知道,原始数组为:41  11  7  16  25  4  23  32  31  22  9  1  22  3  7  31  6  10,以排升序为例,接下来进行分步操作。

  第一步:数组长度为19,故第一步的步长为19/1.3=14。故第0个元素41与第14个元素3进行比较,41大于3,进行交换;同理,第1个元素11与第15个元素7进行比较,11大于7,进行交换;以此类推,比较到最后一个元素后,此时数组变成:3  7  18  6  10  25  4  23  32  31  22  9  1  22  41  11  31  7  16

  第二步:第一步的步长为14,故第二步的步长为14/1.3=10。故第0个元素3与第10个元素22进行比较,3小于10,不进行交换;同理,第1个元素7与第11个元素9进行比较,7小于9,不进行交换;以此类推,比较到最后一个元素后,此时数组变成:3  7  1  6  10  11  4  7  16  31  22  9  18  22  41  25  31  23  32

  第三步:第二步的步长为10,故第三步的步长为10/1.3=7。故第0个元素3与第7个元素7进行比较,3小于7,不进行交换;同理,第1个元素7与第8个元素16进行比较,7小于9,不进行交换;以此类推,比较到最后一个元素后,此时数组变成:3  7  1  6  9  11  4  7  16  31  22  10  18  22  41  25  31  23  32

  第四步:第三步的步长为10,故第四步的步长为10/1.3=7。故第0个元素3与第7个元素7进行比较,3小于7,不进行交换;同理,第1个元素7与第8个元素16进行比较,7小于9,不进行交换;以此类推,比较到最后一个元素后,此时数组变成:3  7  1  6  9  11  4  7  16  31  22  10  18  22  41  25  31  23  32

  第五步;第四步的步长为7,故第五步的步长为7/1.3=5。故第0个元素3与第5个元素11进行比较,3小于11,不进行交换;同理,第1个元素7与第6个元素4进行比较,7大于4,进行交换;以此类推,比较到最后一个元素后,此时数组变成:3  4  1  6  9  11  7  7  16  31  22  10  18  22  41  25  31  23  32

  第六步;第五步的步长为5,故第六步的步长为5/1.3=3。故第0个元素3与第3个元素6进行比较,3小于6,不进行交换;同理,第1个元素4与第4个元素9进行比较,4大于9,不进行交换;以此类推,比较到最后一个元素后,此时数组变成:3  4  1  6  7  10  7  9  11  18  22  16  31  22  23  25  31  41  32
  第七步;第六步的步长为3,故第七步的步长为3/1.3=2。故第0个元素3与第2个元素1进行比较,3大于1,进行交换;同理,第1个元素4与第3个元素6进行比较,4小于6,不进行交换;以此类推,比较到最后一个元素后,此时数组变成:1  4  3  6  7  9  7  10  11  16  22  18  23  22  31  25  31  41  32
  第八步;第七步的步长为2,故第八步的步长为2/1.3=1。故第0个元素1与第1个元素4进行比较,1大于4,不进行交换;同理,第1个元素4与第2个元素3进行比较,4大于3,进行交换;以此类推,比较到最后一个元素后,此时数组变成:1  3  4  6  7  7  9  10  11  16  18  22  22  23  25  25  31  31  32  41

(2) 梳排序的实现

  本次排序算法采用C++模版编程来实现。

#include <iostream>
#include <iterator>
#include <iomanip>

using namespace std;


template<class T,size_t N>
void PrintArr(T (&arr)[N])
{
    copy(arr,arr + N,ostream_iterator<T>(cout," "));
    cout << endl;
}


template<class T,size_t N>
void CombSort(T (&arr)[N])
{
    size_t gap(N);
    while(gap > 0) {
        gap /= 1.3;
        for(size_t i = 0; i+gap < N; i++) {
            if(arr[i] > arr[i+gap]) {
                swap(arr[i],arr[i+gap]);
            }
        }
        PrintArr(arr);
    }
}

template<class SortFunc>
void Test(SortFunc sort)
{
    int arr[]= {41,11,18,7,16,25,4,23,32,31,22,9,1,22,3,7,31,6,10};
    PrintArr(arr);
    sort(arr);
    cout << "The final:" << endl;
    PrintArr(arr);
}
原始数组为:41  11  7  16  25  4  23  32  31  22  9  1  22  3  7  31  6  10

程序运行结果为:1  3  4  6  7  7  9  10  11  16  18  22  22  23  25  25  31  31  32  41


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值