mirror of
https://github.com/duke-git/lancet.git
synced 2025-09-26 19:41:20 +08:00
67 lines
2.2 KiB
Go
67 lines
2.2 KiB
Go
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
|
|
// Use of this source code is governed by MIT license
|
|
|
|
// Package algorithm contain some basic algorithm functions. eg. sort, search, list, linklist, stack, queue, tree, graph.
|
|
package algorithm
|
|
|
|
import "github.com/duke-git/lancet/v2/constraints"
|
|
|
|
// Search algorithms see https://github.com/TheAlgorithms/Go/tree/master/search
|
|
|
|
// LinearSearch return the index of target in slice base on equal function.
|
|
// If not found return -1
|
|
// Play: https://go.dev/play/p/IsS7rgn5s3x
|
|
func LinearSearch[T any](slice []T, target T, equal func(a, b T) bool) int {
|
|
for i, v := range slice {
|
|
if equal(v, target) {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// BinarySearch return the index of target within a sorted slice, use binary search (recursive call itself).
|
|
// If not found return -1.
|
|
// Play: https://go.dev/play/p/t6MeGiUSN47
|
|
func BinarySearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int {
|
|
if highIndex < lowIndex || len(sortedSlice) == 0 {
|
|
return -1
|
|
}
|
|
|
|
midIndex := int(lowIndex + (highIndex-lowIndex)/2)
|
|
isMidValGreatTarget := comparator.Compare(sortedSlice[midIndex], target) == 1
|
|
isMidValLessTarget := comparator.Compare(sortedSlice[midIndex], target) == -1
|
|
|
|
if isMidValGreatTarget {
|
|
return BinarySearch(sortedSlice, target, lowIndex, midIndex-1, comparator)
|
|
} else if isMidValLessTarget {
|
|
return BinarySearch(sortedSlice, target, midIndex+1, highIndex, comparator)
|
|
}
|
|
|
|
return midIndex
|
|
}
|
|
|
|
// BinaryIterativeSearch return the index of target within a sorted slice, use binary search (no recursive).
|
|
// If not found return -1.
|
|
// Play: https://go.dev/play/p/Anozfr8ZLH3
|
|
func BinaryIterativeSearch[T any](sortedSlice []T, target T, lowIndex, highIndex int, comparator constraints.Comparator) int {
|
|
startIndex := lowIndex
|
|
endIndex := highIndex
|
|
|
|
var midIndex int
|
|
for startIndex <= endIndex {
|
|
midIndex = int(startIndex + (endIndex-startIndex)/2)
|
|
isMidValGreatTarget := comparator.Compare(sortedSlice[midIndex], target) == 1
|
|
isMidValLessTarget := comparator.Compare(sortedSlice[midIndex], target) == -1
|
|
|
|
if isMidValGreatTarget {
|
|
endIndex = midIndex - 1
|
|
} else if isMidValLessTarget {
|
|
startIndex = midIndex + 1
|
|
} else {
|
|
return midIndex
|
|
}
|
|
}
|
|
return -1
|
|
}
|