diff --git a/algorithm/sorter.go b/algorithm/sorter.go index 9223337..84096a8 100644 --- a/algorithm/sorter.go +++ b/algorithm/sorter.go @@ -7,7 +7,7 @@ package algorithm import "github.com/duke-git/lancet/v2/lancetconstraints" // BubbleSort use bubble to sort slice. -func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { +func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) { for i := 0; i < len(slice); i++ { for j := 0; j < len(slice)-1-i; j++ { isCurrGreatThanNext := comparator.Compare(slice[j], slice[j+1]) == 1 @@ -16,38 +16,26 @@ func BubbleSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { } } } - 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-- +func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) { + for i := 0; i < len(slice); i++ { + for j := i; j > 0; j-- { + isPreLessThanCurrent := comparator.Compare(slice[j], slice[j-1]) == -1 + if isPreLessThanCurrent { + swap(slice, j, j-1) + } else { + break + } } - - slice[preIndex+1] = currentItem } - - return slice } // SelectionSort use selection to sort slice. -func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { +func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) { for i := 0; i < len(slice); i++ { min := i - for j := i + 1; j < len(slice); j++ { if comparator.Compare(slice[j], slice[min]) == -1 { min = j @@ -55,15 +43,11 @@ func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) [] } swap(slice, i, min) } - return slice } // ShellSort shell sort slice. -func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { +func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) { size := len(slice) - if size <= 1 { - return slice - } gap := 1 for gap < size/3 { @@ -76,21 +60,17 @@ func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { swap(slice, j, j-gap) } } - gap /= 3 + gap = gap / 3 } - - return slice } // QuickSort quick sorting for slice, lowIndex is 0 and highIndex is len(slice)-1 -func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T { +func QuickSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) { if lowIndex < highIndex { p := partition(slice, lowIndex, highIndex, comparator) QuickSort(slice, lowIndex, p-1, comparator) QuickSort(slice, p+1, highIndex, comparator) } - - return slice } // partition split slice into two parts @@ -110,7 +90,7 @@ func partition[T any](slice []T, lowIndex, highIndex int, comparator lancetconst } // HeapSort use heap to sort slice -func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { +func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) { size := len(slice) for i := size/2 - 1; i >= 0; i-- { @@ -120,8 +100,6 @@ func HeapSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { swap(slice, 0, j) sift(slice, 0, j-1, comparator) } - - return slice } func sift[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) { @@ -145,15 +123,17 @@ func sift[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraint } // MergeSort merge sorting for slice -func MergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) []T { +func MergeSort[T any](slice []T, comparator lancetconstraints.Comparator) { + mergeSort(slice, 0, len(slice)-1, comparator) +} + +func mergeSort[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) { if lowIndex < highIndex { mid := (lowIndex + highIndex) / 2 - MergeSort(slice, lowIndex, mid, comparator) - MergeSort(slice, mid+1, highIndex, comparator) + mergeSort(slice, lowIndex, mid, comparator) + mergeSort(slice, mid+1, highIndex, comparator) merge(slice, lowIndex, mid, highIndex, comparator) } - - return slice } func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator lancetconstraints.Comparator) { diff --git a/algorithm/sorter_test.go b/algorithm/sorter_test.go index a3bba50..5f05b2b 100644 --- a/algorithm/sorter_test.go +++ b/algorithm/sorter_test.go @@ -28,22 +28,15 @@ func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int { return 1 } return 0 - - //decending order - // if p1.Age > p2.Age { - // return -1 - // } else if p1.Age < p2.Age { - // return 1 - // } } -var peoples = []people{ - {Name: "a", Age: 20}, - {Name: "b", Age: 10}, - {Name: "c", Age: 17}, - {Name: "d", Age: 8}, - {Name: "e", Age: 28}, -} +// var peoples = []people{ +// {Name: "a", Age: 20}, +// {Name: "b", Age: 10}, +// {Name: "c", Age: 17}, +// {Name: "d", Age: 8}, +// {Name: "e", Age: 28}, +// } type intComparator struct{} @@ -60,40 +53,51 @@ func (c *intComparator) Compare(v1 any, v2 any) int { return 0 } -var intSlice = []int{2, 1, 5, 3, 6, 4} +// var intSlice = []int{2, 1, 5, 3, 6, 4} func TestBubbleSortForStructSlice(t *testing.T) { asssert := internal.NewAssert(t, "TestBubbleSortForStructSlice") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} - sortedPeopleByAge := BubbleSort(peoples, comparator) - t.Log(sortedPeopleByAge) + BubbleSort(peoples, comparator) expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" - actual := fmt.Sprintf("%v", sortedPeopleByAge) + actual := fmt.Sprintf("%v", peoples) asssert.Equal(expected, actual) } func TestBubbleSortForIntSlice(t *testing.T) { asssert := internal.NewAssert(t, "TestBubbleSortForIntSlice") - + numbers := []int{2, 1, 5, 3, 6, 4} comparator := &intComparator{} - sortedInt := BubbleSort(intSlice, comparator) - expected := []int{1, 2, 3, 4, 5, 6} + BubbleSort(numbers, comparator) - asssert.Equal(expected, sortedInt) + asssert.Equal([]int{1, 2, 3, 4, 5, 6}, numbers) } func TestInsertionSort(t *testing.T) { asssert := internal.NewAssert(t, "TestInsertionSort") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} - sortedPeopleByAge := InsertionSort(peoples, comparator) - t.Log(sortedPeopleByAge) + InsertionSort(peoples, comparator) - expected := "[{e 28} {a 20} {c 17} {b 10} {d 8}]" - actual := fmt.Sprintf("%v", sortedPeopleByAge) + expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" + actual := fmt.Sprintf("%v", peoples) asssert.Equal(expected, actual) } @@ -101,12 +105,18 @@ func TestInsertionSort(t *testing.T) { func TestSelectionSort(t *testing.T) { asssert := internal.NewAssert(t, "TestSelectionSort") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} - sortedPeopleByAge := SelectionSort(peoples, comparator) - t.Log(sortedPeopleByAge) + SelectionSort(peoples, comparator) expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" - actual := fmt.Sprintf("%v", sortedPeopleByAge) + actual := fmt.Sprintf("%v", peoples) asssert.Equal(expected, actual) } @@ -114,12 +124,18 @@ func TestSelectionSort(t *testing.T) { func TestShellSort(t *testing.T) { asssert := internal.NewAssert(t, "TestShellSort") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} - sortedPeopleByAge := ShellSort(peoples, comparator) - t.Log(sortedPeopleByAge) + ShellSort(peoples, comparator) expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" - actual := fmt.Sprintf("%v", sortedPeopleByAge) + actual := fmt.Sprintf("%v", peoples) asssert.Equal(expected, actual) } @@ -127,12 +143,18 @@ func TestShellSort(t *testing.T) { func TestQuickSort(t *testing.T) { asssert := internal.NewAssert(t, "TestQuickSort") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} - sortedPeopleByAge := QuickSort(peoples, 0, len(peoples)-1, comparator) - t.Log(sortedPeopleByAge) + QuickSort(peoples, 0, len(peoples)-1, comparator) expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" - actual := fmt.Sprintf("%v", sortedPeopleByAge) + actual := fmt.Sprintf("%v", peoples) asssert.Equal(expected, actual) } @@ -140,12 +162,18 @@ func TestQuickSort(t *testing.T) { func TestHeapSort(t *testing.T) { asssert := internal.NewAssert(t, "TestHeapSort") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} - sortedPeopleByAge := HeapSort(peoples, comparator) - t.Log(sortedPeopleByAge) + HeapSort(peoples, comparator) expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" - actual := fmt.Sprintf("%v", sortedPeopleByAge) + actual := fmt.Sprintf("%v", peoples) asssert.Equal(expected, actual) } @@ -153,12 +181,18 @@ func TestHeapSort(t *testing.T) { func TestMergeSort(t *testing.T) { asssert := internal.NewAssert(t, "TestMergeSort") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} - sortedPeopleByAge := MergeSort(peoples, 0, len(peoples)-1, comparator) - t.Log(sortedPeopleByAge) + MergeSort(peoples, comparator) expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" - actual := fmt.Sprintf("%v", sortedPeopleByAge) + actual := fmt.Sprintf("%v", peoples) asssert.Equal(expected, actual) } @@ -166,6 +200,13 @@ func TestMergeSort(t *testing.T) { func TestCountSort(t *testing.T) { asssert := internal.NewAssert(t, "TestCountSort") + peoples := []people{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, + } comparator := &peopleAgeComparator{} sortedPeopleByAge := CountSort(peoples, comparator) t.Log(sortedPeopleByAge)