mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-13 17:22:27 +08:00
experimental feature, algorithm/sorter.go try to implements sort function with go generics
This commit is contained in:
53
algorithm/sorter.go
Normal file
53
algorithm/sorter.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package algorithm contain some algorithm functions. eg. sort, find, list, linklist, stack, queue, tree, graph. TODO
|
||||||
|
package algorithm
|
||||||
|
|
||||||
|
import "github.com/duke-git/lancet/lancetconstraints"
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
for j := i + 1; j < len(slice); j++ {
|
||||||
|
if comparator.Compare(slice[j], slice[min]) == -1 {
|
||||||
|
min = j
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swap(slice, i, min)
|
||||||
|
}
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
|
// func QuickSort[T comparable](slice []T, low, high int) []T {
|
||||||
|
// if low < high {
|
||||||
|
// var p int
|
||||||
|
// slice, p = partitionForQuickSort(slice, low, high)
|
||||||
|
// slice = quickSort(slice, low, p-1)
|
||||||
|
// slice = quickSort(slice, p+1, high)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return slice
|
||||||
|
// }
|
||||||
|
|
||||||
|
// swap two slice value at index i and j
|
||||||
|
func swap[T any](slice []T, i, j int) {
|
||||||
|
slice[i], slice[j] = slice[j], slice[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// func partition[T comparable](slice []T, low, high int) ([]T, int) {
|
||||||
|
// p := slice[high]
|
||||||
|
// i := low
|
||||||
|
// for j := low; j < high; j++ {
|
||||||
|
// //???, error: comparable don't support operator <
|
||||||
|
// if slice[j] < p {
|
||||||
|
// slice[i], slice[j] = slice[j], slice[i]
|
||||||
|
// i++
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// slice[i], slice[high] = slice[high], slice[i]
|
||||||
|
|
||||||
|
// return slice, i
|
||||||
|
// }
|
||||||
58
algorithm/sorter_test.go
Normal file
58
algorithm/sorter_test.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package algorithm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// People test mock data
|
||||||
|
type People struct {
|
||||||
|
Name string
|
||||||
|
Age int
|
||||||
|
}
|
||||||
|
|
||||||
|
// PeopleAageComparator sort people slice by age field
|
||||||
|
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)
|
||||||
|
|
||||||
|
//ascending order
|
||||||
|
if p1.Age < p2.Age {
|
||||||
|
return -1
|
||||||
|
} else if p1.Age > p2.Age {
|
||||||
|
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},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSelectionSort(t *testing.T) {
|
||||||
|
asssert := internal.NewAssert(t, "TestSelectionSort")
|
||||||
|
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)
|
||||||
|
}
|
||||||
13
lancetconstraints/constraints.go
Normal file
13
lancetconstraints/constraints.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
||||||
|
// Use of this source code is governed by MIT license
|
||||||
|
|
||||||
|
// Package lancetconstraints contain some comstomer constraints.
|
||||||
|
package lancetconstraints
|
||||||
|
|
||||||
|
// Comparator is for comparing two values
|
||||||
|
type Comparator interface {
|
||||||
|
// Compare v1 and v2
|
||||||
|
// Ascending order: should return 1 -> v1 > v2, 0 -> v1 = v2, -1 -> v1 < v2
|
||||||
|
// Descending order: should return 1 -> v1 < v2, 0 -> v1 = v2, -1 -> v1 > v2
|
||||||
|
Compare(v1, v2 interface{}) int
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package myconstraints
|
|
||||||
|
|
||||||
type Number interface {
|
|
||||||
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64 | complex64 | complex128
|
|
||||||
}
|
|
||||||
@@ -5,31 +5,6 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
// func quickSort[T comparable](slice []T, low, high int) []T {
|
|
||||||
// if low < high {
|
|
||||||
// var p int
|
|
||||||
// slice, p = partitionForQuickSort(slice, low, high)
|
|
||||||
// slice = quickSort(slice, low, p-1)
|
|
||||||
// slice = quickSort(slice, p+1, high)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return slice
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func partitionForQuickSort[T comparable](slice []T, low, high int) ([]T, int) {
|
|
||||||
// p := slice[high]
|
|
||||||
// i := low
|
|
||||||
// for j := low; j < high; j++ {
|
|
||||||
// //???, error: comparable don't support operator <
|
|
||||||
// if slice[j] < p {
|
|
||||||
// slice[i], slice[j] = slice[j], slice[i]
|
|
||||||
// i++
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// slice[i], slice[high] = slice[high], slice[i]
|
|
||||||
// return slice, i
|
|
||||||
// }
|
|
||||||
|
|
||||||
// sliceValue return the reflect value of a slice
|
// sliceValue return the reflect value of a slice
|
||||||
func sliceValue(slice interface{}) reflect.Value {
|
func sliceValue(slice interface{}) reflect.Value {
|
||||||
v := reflect.ValueOf(slice)
|
v := reflect.ValueOf(slice)
|
||||||
|
|||||||
Reference in New Issue
Block a user