diff --git a/sorting/shell.go b/sorting/shell.go new file mode 100644 index 0000000..7f192a2 --- /dev/null +++ b/sorting/shell.go @@ -0,0 +1,37 @@ +package sorting + +type shell struct{} + +func (*shell) Sort(items Sortable) { + len := items.Len() + gap := 1 + + // Calculating gap maximum value. + // This is for "Sedgewick gap sequence" variation. + // Another sequences can be used + for gap < len/3 { + gap = gap*3 + 1 + } + + // This loop needed to progressively degrease gap until siple insertion + // sort will be used + for gap >= 1 { + + // Insertion sort loop + for i := gap; i < len; i++ { + + // Instead of comparing adjacent elements we compare + // gap distance elements and swap them + for j := i; j >= gap && items.Less(j, j-gap); j -= gap { + items.Swap(j, j-gap) + } + } + + // "Sedgewick gap sequence" + gap = gap / 3 + } +} + +func NewShell() Sorter { + return &shell{} +} diff --git a/sorting/sort_test.go b/sorting/sort_test.go index a45fca5..1973220 100644 --- a/sorting/sort_test.go +++ b/sorting/sort_test.go @@ -23,3 +23,13 @@ func BenchmarkInsertion(b *testing.B) { BenchmarkSort(10000, NewInsertion()) } } + +func TestShell(t *testing.T) { + CheckSorter(NewShell()) +} + +func BenchmarkShell(b *testing.B) { + for i := 0; i < b.N; i++ { + BenchmarkSort(10000, NewShell()) + } +}