From 43e0ca7edfa491dcb1e92cef4f421c93d0eacacb Mon Sep 17 00:00:00 2001 From: dudaodong Date: Fri, 14 Jan 2022 18:17:46 +0800 Subject: [PATCH] feat: add ShellSort --- algorithm/sorter.go | 27 ++++++++++++++++++++++++++- algorithm/sorter_test.go | 13 +++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/algorithm/sorter.go b/algorithm/sorter.go index 8205a84..eafe118 100644 --- a/algorithm/sorter.go +++ b/algorithm/sorter.go @@ -10,7 +10,8 @@ import "github.com/duke-git/lancet/lancetconstraints" func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { for i := 0; i < len(slice); i++ { for j := 0; j < len(slice)-1-i; j++ { - if comparator.Compare(slice[j], slice[j+1]) == 1 { + isCurrGreatThanNext := comparator.Compare(slice[j], slice[j+1]) == 1 + if isCurrGreatThanNext { swap(slice, j, j+1) } } @@ -57,6 +58,30 @@ func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) [] return slice } +// ShellSort shell sort slice. +func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { + size := len(slice) + if size <= 1 { + return slice + } + + gap := 1 + for gap < size/3 { + gap = 3*gap + 1 + } + + for gap >= 1 { + for i := gap; i < size; i++ { + for j := i; j >= gap && comparator.Compare(slice[j], slice[j-gap]) == -1; j -= gap { + swap(slice, j, j-gap) + } + } + gap /= 3 + } + + return slice +} + // func QuickSort[T comparable](slice []T, low, high int) []T { // if low < high { // var p int diff --git a/algorithm/sorter_test.go b/algorithm/sorter_test.go index c6522d9..e508a43 100644 --- a/algorithm/sorter_test.go +++ b/algorithm/sorter_test.go @@ -110,3 +110,16 @@ func TestSelectionSort(t *testing.T) { asssert.Equal(expected, actual) } + +func TestShellSort(t *testing.T) { + asssert := internal.NewAssert(t, "TestShellSort") + + comparator := &peopleAageComparator{} + sortedPeopleByAge := ShellSort(peoples, comparator) + t.Log(sortedPeopleByAge) + + expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" + actual := fmt.Sprintf("%v", sortedPeopleByAge) + + asssert.Equal(expected, actual) +}