梳排序(Comb sort)是一种由Wlodzimierz Dobosiewicz于1980年所发明的不稳定排序算法,并由Stephen Lacey和Richard Box于1991年四月号的Byte杂志中推广。梳排序是改良自冒泡排序和快速排序,其要旨在于消除乌龟,亦即在数组尾部的小数值,这些数值是造成冒泡排序缓慢的主因。相对地,兔子,亦即在数组前端的大数值,不影响冒泡排序的性能。
在冒泡排序中,只比较数组中相邻的二项,即比较的二项的间距(Gap)是1,梳排序提出此间距其实可大于1,改自插入排序的希尔排序同样提出相同观点。梳排序中,开始时的间距设置为数组长度,并在循环中以固定比率递减,通常递减率设置为1.3。在一次循环中,梳排序如同冒泡排序一样把数组从首到尾扫描一次,比较及交换两项,不同的是两项的间距不固定于1。如果间距递减至1,梳排序假定输入数组大致排序好,并以冒泡排序作最后检查及修正。
示例代码:
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {

	slice := generateSlice(20)
	fmt.Println("\n--- Unsorted --- \n\n", slice)
	combsort(slice)
	fmt.Println("\n--- Sorted ---\n\n", slice, "\n")
}

func generateSlice(size int) []int {

	slice := make([]int, size, size)
	rand.Seed(time.Now().UnixNano())
	for i := 0; i < size; i++ {
		slice[i] = rand.Intn(999) - rand.Intn(999)
	}
	return slice
}
 
func combsort(items []int) {
	var (
		n = len(items)
		gap = len(items)
		shrink = 1.3
		swapped = true
	)
	
	for swapped {
		swapped = false
        	gap = int(float64(gap) / shrink)
        	if gap < 1 {
			gap = 1
		}
		for i := 0; i+gap < n; i++ {
			if items[i] > items[i+gap] {
				items[i+gap], items[i] = items[i], items[i+gap]
				swapped = true
			}	
		}
	}
}

输出:

--- Unsorted ---

 [-317 -381 -14 -215 -590 -243 -412 380 -312 925 158 -46 177 22 -482 273 217 514 -392 424]

--- Sorted ---

 [-590 -482 -412 -392 -381 -317 -312 -243 -215 -46 -14 22 158 177 217 273 380 424 514 925]