mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
refactor: rewrite sort function
This commit is contained in:
@@ -7,7 +7,7 @@ package algorithm
|
|||||||
import "github.com/duke-git/lancet/v2/lancetconstraints"
|
import "github.com/duke-git/lancet/v2/lancetconstraints"
|
||||||
|
|
||||||
// BubbleSort use bubble to sort slice.
|
// 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 i := 0; i < len(slice); i++ {
|
||||||
for j := 0; j < len(slice)-1-i; j++ {
|
for j := 0; j < len(slice)-1-i; j++ {
|
||||||
isCurrGreatThanNext := comparator.Compare(slice[j], slice[j+1]) == 1
|
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.
|
// InsertionSort use insertion to sort slice.
|
||||||
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
func InsertionSort[T any](slice []T, comparator lancetconstraints.Comparator) {
|
||||||
size := len(slice)
|
for i := 0; i < len(slice); i++ {
|
||||||
if size <= 1 {
|
for j := i; j > 0; j-- {
|
||||||
return slice
|
isPreLessThanCurrent := comparator.Compare(slice[j], slice[j-1]) == -1
|
||||||
}
|
if isPreLessThanCurrent {
|
||||||
|
swap(slice, j, j-1)
|
||||||
for i := 1; i < size; i++ {
|
} else {
|
||||||
currentItem := slice[i]
|
break
|
||||||
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] = currentItem
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return slice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SelectionSort use selection to sort 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++ {
|
for i := 0; i < len(slice); i++ {
|
||||||
min := i
|
min := i
|
||||||
|
|
||||||
for j := i + 1; j < len(slice); j++ {
|
for j := i + 1; j < len(slice); j++ {
|
||||||
if comparator.Compare(slice[j], slice[min]) == -1 {
|
if comparator.Compare(slice[j], slice[min]) == -1 {
|
||||||
min = j
|
min = j
|
||||||
@@ -55,15 +43,11 @@ func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []
|
|||||||
}
|
}
|
||||||
swap(slice, i, min)
|
swap(slice, i, min)
|
||||||
}
|
}
|
||||||
return slice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShellSort shell sort 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)
|
size := len(slice)
|
||||||
if size <= 1 {
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
gap := 1
|
gap := 1
|
||||||
for gap < size/3 {
|
for gap < size/3 {
|
||||||
@@ -76,21 +60,17 @@ func ShellSort[T any](slice []T, comparator lancetconstraints.Comparator) []T {
|
|||||||
swap(slice, j, j-gap)
|
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
|
// 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 {
|
if lowIndex < highIndex {
|
||||||
p := partition(slice, lowIndex, highIndex, comparator)
|
p := partition(slice, lowIndex, highIndex, comparator)
|
||||||
QuickSort(slice, lowIndex, p-1, comparator)
|
QuickSort(slice, lowIndex, p-1, comparator)
|
||||||
QuickSort(slice, p+1, highIndex, comparator)
|
QuickSort(slice, p+1, highIndex, comparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
return slice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// partition split slice into two parts
|
// 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
|
// 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)
|
size := len(slice)
|
||||||
|
|
||||||
for i := size/2 - 1; i >= 0; i-- {
|
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)
|
swap(slice, 0, j)
|
||||||
sift(slice, 0, j-1, comparator)
|
sift(slice, 0, j-1, comparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
return slice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sift[T any](slice []T, lowIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
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
|
// 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 {
|
if lowIndex < highIndex {
|
||||||
mid := (lowIndex + highIndex) / 2
|
mid := (lowIndex + highIndex) / 2
|
||||||
MergeSort(slice, lowIndex, mid, comparator)
|
mergeSort(slice, lowIndex, mid, comparator)
|
||||||
MergeSort(slice, mid+1, highIndex, comparator)
|
mergeSort(slice, mid+1, highIndex, comparator)
|
||||||
merge(slice, lowIndex, mid, highIndex, comparator)
|
merge(slice, lowIndex, mid, highIndex, comparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
return slice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
func merge[T any](slice []T, lowIndex, midIndex, highIndex int, comparator lancetconstraints.Comparator) {
|
||||||
|
|||||||
@@ -28,22 +28,15 @@ func (pc *peopleAgeComparator) Compare(v1 any, v2 any) int {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
//decending order
|
|
||||||
// if p1.Age > p2.Age {
|
|
||||||
// return -1
|
|
||||||
// } else if p1.Age < p2.Age {
|
|
||||||
// return 1
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var peoples = []people{
|
// var peoples = []people{
|
||||||
{Name: "a", Age: 20},
|
// {Name: "a", Age: 20},
|
||||||
{Name: "b", Age: 10},
|
// {Name: "b", Age: 10},
|
||||||
{Name: "c", Age: 17},
|
// {Name: "c", Age: 17},
|
||||||
{Name: "d", Age: 8},
|
// {Name: "d", Age: 8},
|
||||||
{Name: "e", Age: 28},
|
// {Name: "e", Age: 28},
|
||||||
}
|
// }
|
||||||
|
|
||||||
type intComparator struct{}
|
type intComparator struct{}
|
||||||
|
|
||||||
@@ -60,40 +53,51 @@ func (c *intComparator) Compare(v1 any, v2 any) int {
|
|||||||
return 0
|
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) {
|
func TestBubbleSortForStructSlice(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestBubbleSortForStructSlice")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := BubbleSort(peoples, comparator)
|
BubbleSort(peoples, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
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)
|
asssert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBubbleSortForIntSlice(t *testing.T) {
|
func TestBubbleSortForIntSlice(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestBubbleSortForIntSlice")
|
asssert := internal.NewAssert(t, "TestBubbleSortForIntSlice")
|
||||||
|
numbers := []int{2, 1, 5, 3, 6, 4}
|
||||||
comparator := &intComparator{}
|
comparator := &intComparator{}
|
||||||
sortedInt := BubbleSort(intSlice, comparator)
|
BubbleSort(numbers, comparator)
|
||||||
expected := []int{1, 2, 3, 4, 5, 6}
|
|
||||||
|
|
||||||
asssert.Equal(expected, sortedInt)
|
asssert.Equal([]int{1, 2, 3, 4, 5, 6}, numbers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInsertionSort(t *testing.T) {
|
func TestInsertionSort(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestInsertionSort")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := InsertionSort(peoples, comparator)
|
InsertionSort(peoples, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
|
||||||
|
|
||||||
expected := "[{e 28} {a 20} {c 17} {b 10} {d 8}]"
|
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)
|
asssert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
@@ -101,12 +105,18 @@ func TestInsertionSort(t *testing.T) {
|
|||||||
func TestSelectionSort(t *testing.T) {
|
func TestSelectionSort(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestSelectionSort")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := SelectionSort(peoples, comparator)
|
SelectionSort(peoples, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
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)
|
asssert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
@@ -114,12 +124,18 @@ func TestSelectionSort(t *testing.T) {
|
|||||||
func TestShellSort(t *testing.T) {
|
func TestShellSort(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestShellSort")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := ShellSort(peoples, comparator)
|
ShellSort(peoples, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
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)
|
asssert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
@@ -127,12 +143,18 @@ func TestShellSort(t *testing.T) {
|
|||||||
func TestQuickSort(t *testing.T) {
|
func TestQuickSort(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestQuickSort")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := QuickSort(peoples, 0, len(peoples)-1, comparator)
|
QuickSort(peoples, 0, len(peoples)-1, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
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)
|
asssert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
@@ -140,12 +162,18 @@ func TestQuickSort(t *testing.T) {
|
|||||||
func TestHeapSort(t *testing.T) {
|
func TestHeapSort(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestHeapSort")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := HeapSort(peoples, comparator)
|
HeapSort(peoples, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
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)
|
asssert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
@@ -153,12 +181,18 @@ func TestHeapSort(t *testing.T) {
|
|||||||
func TestMergeSort(t *testing.T) {
|
func TestMergeSort(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestMergeSort")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := MergeSort(peoples, 0, len(peoples)-1, comparator)
|
MergeSort(peoples, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
|
||||||
|
|
||||||
expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]"
|
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)
|
asssert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
@@ -166,6 +200,13 @@ func TestMergeSort(t *testing.T) {
|
|||||||
func TestCountSort(t *testing.T) {
|
func TestCountSort(t *testing.T) {
|
||||||
asssert := internal.NewAssert(t, "TestCountSort")
|
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{}
|
comparator := &peopleAgeComparator{}
|
||||||
sortedPeopleByAge := CountSort(peoples, comparator)
|
sortedPeopleByAge := CountSort(peoples, comparator)
|
||||||
t.Log(sortedPeopleByAge)
|
t.Log(sortedPeopleByAge)
|
||||||
|
|||||||
Reference in New Issue
Block a user