排序算法——梳排序(Comb sort)【代码实现】

伪代码

function combsort(array input)
    gap := input.size //initialize gap size
    loop until gap = 1 and swaps = 0
        //update the gap value for a next comb. Below is an example
        gap := int(gap / 1.25)
        if gap < 1
          //minimum gap is 1
          gap := 1
        end if
        i := 0
        swaps := 0 //see Bubble Sort for an explanation
        //a single "comb" over the input list
        loop until i + gap >= input.size //see Shell sort for similar idea
            if input[i] > input[i+gap]
                swap(input[i], input[i+gap])
                swaps := 1 // Flag a swap has occurred, so the
                           // list is not guaranteed sorted
            end if
            i := i + 1
        end loop
    end loop
end function

ActionScript

function combSort(input:Array)
{
	var gap:uint = input.length;
	var swapped:Boolean = false;
	while(gap > 1 || swapped)
	{
		gap /= 1.25;
		swapped = false;
		for(var i:uint = 0; i + gap < input.length; i++)
		{
			if(input[i] > input[i+gap])
			{
				var tmp = input[i];
				input[i] = input[i+gap];
				input[i+gap]=tmp;
				swapped = true;
			}
		}
	}
	return input;
}

C

void Combsort11(double a[], int nElements)
{
  int i, j, gap, swapped = 1;
  double temp;
 
  gap = nElements;
  while (gap > 1 || swapped == 1)
  {
    gap = gap * 10 / 13;
    if (gap == 9 || gap == 10) gap = 11;
    if (gap < 1) gap = 1;
    swapped = 0;
    for (i = 0, j = gap; j < nElements; i++, j++)
    {
      if (a[i] > a[j])
      {
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
        swapped = 1;
      }
    }
  }
}

C++

template<class ForwardIterator>
void combsort ( ForwardIterator first, ForwardIterator last )
{
    static const double shrink_factor = 1.247330950103979;
    typedef typename std::iterator_traits<ForwardIterator>::difference_type difference_type;
    difference_type gap = std::distance(first, last);
    bool swaps = true;
 
    while ( (gap > 1) || (swaps == true) ){
        if (gap > 1)
            gap = static_cast<difference_type>(gap/shrink_factor);
 
        swaps = false;
        ForwardIterator itLeft(first);
        ForwardIterator itRight(first); std::advance(itRight, gap);
 
        for ( ; itRight!=last; ++itLeft, ++itRight ){
            if ( (*itRight) < (*itLeft) ){
                std::iter_swap(itLeft, itRight);
                swaps = true;
            }
        }
    }
}

C#

using System;
 
namespace CombSort
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] unsorted = new int[] { 3, 5, 1, 9, 7, 6, 8, 2, 4 };
            Console.WriteLine(string.Join(",", combSort(unsorted)));
        }
        public static int[] combSort(int[] input)
        {
            double gap = input.Length;
            bool swaps = true;
            while (gap > 1 || swaps)
            {
                gap /= 1.247330950103979;
                if (gap < 1) { gap = 1; }
                int i = 0;
                swaps = false;
                while (i + gap < input.Length)
                {
                    int igap = i + (int)gap;
                    if (input[i] > input[igap])
                    {
                        int swap = input[i];
                        input[i] = input[igap];
                        input[igap] = swap;
                        swaps = true;
                    }
                    i++;
                }
            }
            return input;
        }
    }
}

Go

package main
 
import "fmt"
 
func main() {
    a := []int{170, 45, 75, -90, -802, 24, 2, 66}
    fmt.Println("before:", a)
    combSort(a)
    fmt.Println("after: ", a)
}
 
func combSort(a []int) {
    if len(a) < 2 {
        return
    }
    for gap := len(a); ; {
        if gap > 1 {
            gap = gap * 4 / 5
        }
        swapped := false
        for i := 0; ; {
            if a[i] > a[i+gap] {
                a[i], a[i+gap] = a[i+gap], a[i]
                swapped = true
            }
            i++
            if i+gap >= len(a) {
                break
            }
        }
        if gap == 1 && !swapped {
            break
        }
    }
}

Java

public static <E extends Comparable<? super E>> void sort(E[] input) {
    int gap = input.length;
    boolean swapped = true;
    while (gap > 1 || swapped) {
        if (gap > 1) {
            gap = (int) (gap / 1.3);
        }
        swapped = false;
        for (int i = 0; i + gap < input.length; i++) {
            if (input[i].compareTo(input[i + gap]) > 0) {
                E t = input[i];
                input[i] = input[i + gap];
                input[i + gap] = t;
                swapped = true;
            }
        }
    }
}

JavaScript

  // Node 5.4.1 tested implementation (ES6)
  function is_array_sorted(arr) {
      var sorted = true;
      for (var i = 0; i < arr.length - 1; i++) {
          if (arr[i] > arr[i + 1]) {
              sorted = false;
              break;
          }
      }
      return sorted;
  }
 
  // Array to sort
  var arr = [4, 9, 0, 3, 1, 5];
 
  var iteration_count = 0;
  var gap = arr.length - 2;
  var decrease_factor = 1.25;
 
  // Until array is not sorted, repeat iterations
  while (!is_array_sorted(arr)) {
      // If not first gap
      if (iteration_count > 0)
      // Calculate gap
          gap = (gap == 1) ? gap : Math.floor(gap / decrease_factor);
 
      // Set front and back elements and increment to a gap
      var front = 0;
      var back = gap;
      while (back <= arr.length - 1) {
          // If elements are not ordered swap them
          if (arr[front] > arr[back]) {
              var temp = arr[front];
              arr[front] = arr[back];
              arr[back] = temp;
          }
 
          // Increment and re-run swapping
          front += 1;
          back += 1;
      }
      iteration_count += 1;
  }
 
  // Print the sorted array
  console.log(arr);
}

Kotlin

// version 1.1.2
fun <T : Comparable<T>> combSort(input: Array<T>) {
    var gap = input.size
    if (gap <= 1) return  // already sorted
    var swaps = false
    while (gap > 1 || swaps) {
        gap = (gap / 1.247331).toInt()
        if (gap < 1) gap = 1
        var i = 0
        swaps = false
        while (i + gap < input.size) {
            if (input[i] > input[i + gap]) {
                val tmp = input[i]
                input[i] = input[i + gap]
                input[i + gap] = tmp
                swaps = true 
            }
            i++
        }
    }
}  
 
fun main(args: Array<String>) {
    val ia = arrayOf(28, 44, 46, 24, 19, 2, 17, 11, 25, 4)
    println("Unsorted : ${ia.contentToString()}") 
    combSort(ia)
    println("Sorted   : ${ia.contentToString()}") 
    println()
    val ca = arrayOf('X', 'B', 'E', 'A', 'Z', 'M', 'S', 'L', 'Y', 'C')
    println("Unsorted : ${ca.contentToString()}") 
    combSort(ca)
    println("Sorted   : ${ca.contentToString()}") 
}

Perl

sub combSort {
    my @arr = @_;
    my $gap = @arr;
    my $swaps = 1;
    while ($gap > 1 || $swaps) {
        $gap /= 1.25 if $gap > 1;
        $swaps = 0;
        foreach my $i (0 .. $#arr - $gap) {
            if ($arr[$i] > $arr[$i+$gap]) {
                @arr[$i, $i+$gap] = @arr[$i+$gap, $i];
                $swaps = 1;
            }
        }
    }
    return @arr;
}

Perl 6

Translation of: Perl
sub comb_sort ( @a is copy ) {
    my $gap = +@a;
    my $swaps = 1;
    while $gap > 1 or $swaps {
        $gap = ( ($gap * 4) div 5 ) || 1 if $gap > 1;
 
        $swaps = 0;
        for ^(+@a - $gap) -> $i {
            my $j = $i + $gap;
            if @a[$i] > @a[$j] {
                @a[$i, $j] .= reverse;
                $swaps = 1;
            }
        }
    }
    return @a;
}
 
my @weights = (^50).map: { 100 + ( 1000.rand.Int / 10 ) };
say @weights.sort.Str eq @weights.&comb_sort.Str ?? 'ok' !! 'not ok';

PHP

function combSort($arr){
	$gap = count($arr);
        $swap = true;
	while ($gap > 1 || $swap){
		if($gap > 1) $gap /= 1.25;
 
		$swap = false;
		$i = 0;
		while($i+$gap < count($arr)){
			if($arr[$i] > $arr[$i+$gap]){
				list($arr[$i], $arr[$i+$gap]) = array($arr[$i+$gap],$arr[$i]);
				$swap = true;
			}
			$i++;
		}
	}
	return $arr;
}

PowerShell

function CombSort ($a) {
    $l = $a.Length
	$gap = 11
	while( $gap -lt $l )
	{
		$gap = [Math]::Floor( $gap*1.3 )
	}
	if( $l -gt 1 )
	{
		$hasChanged = $true
		:outer while ($hasChanged -or ( $gap -gt 1 ) ) {
			$count = 0
			$hasChanged = $false
			if( $gap -gt 1 ) {
				$gap = [Math]::Floor( $gap/1.3 )
			} else {
				$l--
			}
			for ($i = 0; $i -lt ( $l - $gap ); $i++) {
				if ($a[$i] -gt $a[$i+$gap]) {
					$a[$i], $a[$i+$gap] = $a[$i+$gap], $a[$i]
					$hasChanged = $true
					$count++
				}
			}
		}
	}
	$a
}
 
$l = 100; CombSort ( 1..$l | ForEach-Object { $Rand = New-Object Random }{ $Rand.Next( -( $l - 1 ), $l - 1 ) } )

Python

>>> def combsort(input):
    gap = len(input)
    swaps = True
    while gap > 1 or swaps:
        gap = max(1, int(gap / 1.25))  # minimum gap is 1
        swaps = False
        for i in range(len(input) - gap):
            j = i+gap
            if input[i] > input[j]:
                input[i], input[j] = input[j], input[i]
                swaps = True
 
 
>>> y = [88, 18, 31, 44, 4, 0, 8, 81, 14, 78, 20, 76, 84, 33, 73, 75, 82, 5, 62, 70]
>>> combsort(y)
>>> assert y == sorted(y)
>>> y
[0, 4, 5, 8, 14, 18, 20, 31, 33, 44, 62, 70, 73, 75, 76, 78, 81, 82, 84, 88]
>>> 

Ruby

class Array
  def combsort!
    gap = size
    swaps = true
    while gap > 1 or swaps
      gap = [1, (gap / 1.25).to_i].max
      swaps = false
      0.upto(size - gap - 1) do |i|
        if self[i] > self[i+gap]
          self[i], self[i+gap] = self[i+gap], self[i]
          swaps = true
        end
      end
    end
    self
  end
end
 
p [23, 76, 99, 58, 97, 57, 35, 89, 51, 38, 95, 92, 24, 46, 31, 24, 14, 12, 57, 78].combsort!

Swift

func combSort(inout list:[Int]) {
    var swapped = true
    var gap = list.count
 
    while gap > 1 || swapped {
        gap = gap * 10 / 13
 
        if gap == 9 || gap == 10 {
            gap = 11
        } else if gap < 1 {
            gap = 1
        }
 
        swapped = false
 
        for var i = 0, j = gap; j < list.count; i++, j++ {
            if list[i] > list[j] {
                (list[i], list[j]) = (list[j], list[i])
                swapped = true
            }
        }
    }
}

更多代码,持续更新!
整理自网络。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辕门骁骑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值