梳排序(Comb sort)是一种不稳定排序算法,其改良于冒泡排序和快速排序。
在冒泡排序中,只比较阵列中相邻的两项,即比较的间距为1,梳排序提出此间距其实可以大于1,梳排序中,开始时的间距设定为阵列长度,并在循环中以固定的比率递减,通常递减率为1.3,该数字是原作者通过实验得到的最有效的递减率,因为编程中乘法比除法块,所以会取递减率的倒数与间距相乘,即0.8.其实当间距为1的时候,梳排序就是冒泡排序,而间距大于1的时候,梳排序的就是尽量把小的数字往前移动并保证此次间隔内的组是有序的。
例如:当间隔为6时,保证间隔为6的数字之间是有序的,
当间隔为4时,保证间隔为4的数字之间是有序的,
当间隔为3时,保证间隔为3的数字之间是有序的,
当间隔为2时,保证间隔为2的数字之间是有序的,
当间隔为1时,为冒泡排序,调整最后顺序使两两之间有序。

示例:

假设待数组[10 4 3 9 6 5 2 1 7 8]

待排数组长度为10,而10÷1.3=8,则比较10和7,4和8,并做交换

交换后的结果为

[7 4 3 9 6 5 2 1 10 8]

第二次循环,更新间距为8÷1.3=6,比较7和2,4和1,3和10,9和8

7和2,4和1,9和8需要交换,交换后的结果为

[2 1 3 8 6 5 7 4 10 9]

第三次循环,更新距离为4,比较2和6,1和5,3和7,8和4,6和10,5和9

8和4需要交换

[2 1 3 4 6 5 7 8 10 9]

第四次循环,更新距离为3,比较2和4,1和6,3和5,4和7,6和8,5和10,7和9,不需要交换

第五次循环,更新距离为2,比较2和3,1和4,3和6,4和5,6和7,5和8,7和10,8和9,不需要交换

第六次循环,更新距离为1,为冒泡排序。

[1 2 3 4 5 6 7 8 9 10]

交换后排序结束,顺序输出即可得到[1 2 3 4 5 6 7 8 9 10]

 

C++实现:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 template <typename T>
 5 void my_swap (T &a, T &b) {
 6     T temp = a;
 7     a = b;
 8     b = temp;
 9 }
10 
11 template <typename T>
12 void comb_sort(T arr[], int len) {
13     int step = int(len * 0.8);   // 0.8 = 1 / 1.3
14     while (step >= 1) {
15         for (int i = 0; i < len; ++i) {
16             int des = i + step;
17             if ((des < len) && (arr[i] > arr[des])) {
18                 my_swap(arr[i], arr[des]);
19             } else if (des >= len) {
20                 break;
21             }   
22         }   
23         step *= 0.8;
24     }   
25 }
26 
27 int main() {
28     int arr[] = {1, 0, 3, 56, 32, 2, 3, 100, 35, 45, 76, 2, 564, 4}; 
29     int len = sizeof(arr) / sizeof(arr[0]);
30     comb_sort(arr, len);
31     std::cout << "sort over:" << std::endl;
32     for (int i = 0; i < len; ++i) {
33         std::cout << arr[i] << std::endl;
34     }   
35 }

 Python实现

 1 #!/usr/bin/python 
 2 # -*- coding: UTF-8 -*-
 3 def comb_sort(items):
 4     list_len = len(items)
 5     step = int(list_len * 0.8)
 6     while (step >= 1):
 7         for index in range(0, list_len):
 8             des = index + step
 9             if ((des < list_len) and (items[index] > items[step + index])):
10                 items[index], items[index + step] = items[index + step], items[index]
11             elif (des >= list_len):
12                 break;
13         step = int(step * 0.8)
14 lists = [12, 3, 1, 0, 45, 14, 2, 5, 6, 2, 134, 53, 346, 7]
15 print ("before sort:", lists)
16 comb_sort(lists)
17 print ("after sort:", lists)

 

posted on 2017-11-21 21:08  LyndonYoung  阅读(848)  评论(0编辑  收藏  举报