From d491bea2634726ead72274c4e4e7d61c67b32eb7 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Fri, 14 Jan 2022 17:57:14 +0800 Subject: [PATCH] feat: add BubbleSort and InsertionSort --- algorithm/sorter.go | 38 ++++++++++++++++++++- algorithm/sorter_test.go | 72 +++++++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/algorithm/sorter.go b/algorithm/sorter.go index 77aec69..8205a84 100644 --- a/algorithm/sorter.go +++ b/algorithm/sorter.go @@ -6,7 +6,43 @@ package algorithm import "github.com/duke-git/lancet/lancetconstraints" -// SelectionSort use selection to sort slice, +// BubbleSort use bubble to sort slice. +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 { + swap(slice, j, j+1) + } + } + } + return slice +} + +// InsertionSort use insertion to sort slice. +func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { + size := len(slice) + if size <= 1 { + return slice + } + + for i := 1; i < size; i++ { + currentItem := slice[i] + preIndex := i - 1 + preItem := slice[preIndex] + + isPreLessThanCurrent := comparator.Compare(preItem, currentItem) == -1 + for preIndex >= 0 && isPreLessThanCurrent { + slice[preIndex+1] = slice[preIndex] + preIndex-- + } + + slice[preIndex+1] = preItem + } + + return slice +} + +// SelectionSort use selection to sort slice. func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { for i := 0; i < len(slice); i++ { min := i diff --git a/algorithm/sorter_test.go b/algorithm/sorter_test.go index e6724cb..c6522d9 100644 --- a/algorithm/sorter_test.go +++ b/algorithm/sorter_test.go @@ -8,18 +8,18 @@ import ( ) // People test mock data -type People struct { +type people struct { Name string Age int } // PeopleAageComparator sort people slice by age field -type PeopleAageComparator struct{} +type peopleAageComparator struct{} // Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator -func (pc *PeopleAageComparator) Compare(v1 interface{}, v2 interface{}) int { - p1, _ := v1.(People) - p2, _ := v2.(People) +func (pc *peopleAageComparator) Compare(v1 interface{}, v2 interface{}) int { + p1, _ := v1.(people) + p2, _ := v2.(people) //ascending order if p1.Age < p2.Age { @@ -37,7 +37,7 @@ func (pc *PeopleAageComparator) Compare(v1 interface{}, v2 interface{}) int { // } } -var peoples = []People{ +var peoples = []people{ {Name: "a", Age: 20}, {Name: "b", Age: 10}, {Name: "c", Age: 17}, @@ -45,9 +45,63 @@ var peoples = []People{ {Name: "e", Age: 28}, } -func TestSelectionSort(t *testing.T) { - asssert := internal.NewAssert(t, "TestSelectionSort") - comparator := &PeopleAageComparator{} +type intComparator struct{} + +func (c *intComparator) Compare(v1 interface{}, v2 interface{}) int { + val1, _ := v1.(int) + val2, _ := v2.(int) + + //ascending order + if val1 < val2 { + return -1 + } else if val1 > val2 { + return 1 + } + return 0 +} + +var intSlice = []int{2, 1, 5, 3, 6, 4} + +func TestBubbleSortForStructSlice(t *testing.T) { + asssert := internal.NewAssert(t, "TestBubbleSortForStructSlice") + + comparator := &peopleAageComparator{} + sortedPeopleByAge := BubbleSort(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) +} + +func TestBubbleSortForIntSlice(t *testing.T) { + asssert := internal.NewAssert(t, "TestBubbleSortForIntSlice") + + comparator := &intComparator{} + sortedInt := BubbleSort(intSlice, comparator) + expected := []int{1, 2, 3, 4, 5, 6} + + asssert.Equal(expected, sortedInt) +} + +func TestInsertionSort(t *testing.T) { + asssert := internal.NewAssert(t, "TestInsertionSort") + + comparator := &peopleAageComparator{} + sortedPeopleByAge := SelectionSort(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) +} + +func TestSelectionSort(t *testing.T) { + asssert := internal.NewAssert(t, "TestSelectionSort") + + comparator := &peopleAageComparator{} sortedPeopleByAge := SelectionSort(peoples, comparator) t.Log(sortedPeopleByAge)