mirror of
https://github.com/hlccd/goSTL.git
synced 2025-10-03 02:15:34 +08:00
将所有文件的目录结构进行调整,以保证使用者下载即可用
This commit is contained in:
116
utils/comparator/bound.go
Normal file
116
utils/comparator/bound.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package comparator
|
||||
|
||||
//@Title comparator
|
||||
//@Description
|
||||
// 可查找有序序列中某一元素的上界和下届
|
||||
// 当该元素存在时,上界和下届返回的下标位置指向该元素
|
||||
// 当该元素不存在时,上界和下届指向下标错位且指向位置并非该元素
|
||||
|
||||
//@title UpperBound
|
||||
//@description
|
||||
// 通过传入的比较函数对待查找数组进行查找以获取待查找元素的上界即不大于它的最大值的下标
|
||||
// 以传入的比较函数进行比较
|
||||
// 如果该元素存在,则上界指向元素为该元素
|
||||
// 如果该元素不存在,上界指向元素为该元素的前一个元素
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待查找数组
|
||||
//@param e interface{} 待查找元素
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return idx int 待查找元素的上界
|
||||
func UpperBound(arr *[]interface{}, e interface{}, Cmp ...Comparator) (idx int) {
|
||||
if arr==nil || (*arr)==nil || len((*arr)) == 0 {
|
||||
return -1
|
||||
}
|
||||
//判断比较函数是否有效
|
||||
var cmp Comparator
|
||||
cmp = nil
|
||||
if len(Cmp) == 0 {
|
||||
cmp = GetCmp(e)
|
||||
} else {
|
||||
cmp = Cmp[0]
|
||||
}
|
||||
if cmp == nil {
|
||||
return -1
|
||||
}
|
||||
//寻找该元素的上界
|
||||
return upperBound(arr, e, cmp)
|
||||
}
|
||||
|
||||
//@title upperBound
|
||||
//@description
|
||||
// 通过传入的比较函数对待查找数组进行查找以获取待查找元素的上界即不大于它的最大值的下标
|
||||
// 以传入的比较函数进行比较
|
||||
// 如果该元素存在,则上界指向元素为该元素,且为最右侧
|
||||
// 如果该元素不存在,上界指向元素为该元素的前一个元素
|
||||
// 以二分查找的方式寻找该元素的上界
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待查找数组
|
||||
//@param e interface{} 待查找元素
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return idx int 待查找元素的上界
|
||||
func upperBound(arr *[]interface{}, e interface{}, cmp Comparator) (idx int) {
|
||||
l, m, r := 0, len((*arr)) / 2, len((*arr))-1
|
||||
for l < r {
|
||||
m = (l + r + 1) / 2
|
||||
if cmp((*arr)[m], e) <= 0 {
|
||||
l = m
|
||||
} else {
|
||||
r = m - 1
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
//@title LowerBound
|
||||
//@description
|
||||
// 通过传入的比较函数对待查找数组进行查找以获取待查找元素的下界即不小于它的最小值的下标
|
||||
// 以传入的比较函数进行比较
|
||||
// 如果该元素存在,则上界指向元素为该元素
|
||||
// 如果该元素不存在,上界指向元素为该元素的后一个元素
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待查找数组
|
||||
//@param e interface{} 待查找元素
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return idx int 待查找元素的下界
|
||||
func LowerBound(arr *[]interface{}, e interface{}, Cmp ...Comparator) (idx int) {
|
||||
if arr==nil || (*arr)==nil || len((*arr)) == 0 {
|
||||
return -1
|
||||
}
|
||||
//判断比较函数是否有效
|
||||
var cmp Comparator
|
||||
cmp = nil
|
||||
if len(Cmp) == 0 {
|
||||
cmp = GetCmp(e)
|
||||
} else {
|
||||
cmp = Cmp[0]
|
||||
}
|
||||
if cmp == nil {
|
||||
return -1
|
||||
}
|
||||
//寻找该元素的下界
|
||||
return lowerBound(arr, e, cmp)
|
||||
}
|
||||
|
||||
//@title lowerBound
|
||||
//@description
|
||||
// 通过传入的比较函数对待查找数组进行查找以获取待查找元素的下界即不小于它的最小值的下标
|
||||
// 以传入的比较函数进行比较
|
||||
// 如果该元素存在,则上界指向元素为该元素,且为最右侧
|
||||
// 如果该元素不存在,上界指向元素为该元素的后一个元素
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待查找数组
|
||||
//@param e interface{} 待查找元素
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return idx int 待查找元素的下界
|
||||
func lowerBound(arr *[]interface{}, e interface{}, cmp Comparator) (idx int) {
|
||||
l, m, r := 0, len((*arr)) / 2, len((*arr))
|
||||
for l < r {
|
||||
m = (l + r) / 2
|
||||
if cmp((*arr)[m], e) >= 0 {
|
||||
r = m
|
||||
} else {
|
||||
l = m + 1
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
278
utils/comparator/comparator.go
Normal file
278
utils/comparator/comparator.go
Normal file
@@ -0,0 +1,278 @@
|
||||
package comparator
|
||||
|
||||
//@Title comparator
|
||||
//@Description
|
||||
// 比较器
|
||||
// 定义了一个比较器类型,该类型可传入两个泛型并返回一个整数判断大小
|
||||
// 该比较器用于定义的数据结构中传入数据之间的比较
|
||||
// 该包内定义了一些自带类型的比较类型
|
||||
// 当使用自定义的数据结构时若不进行比较器的传入则使用默认比较器
|
||||
// 若传入类型非系统自带类型,则返回空比较器同时对数据的传入失败
|
||||
|
||||
// 比较器将会返回数字num
|
||||
// num > 0 ,if a > b
|
||||
// num = 0 ,if a = b
|
||||
// num < 0 ,if a < b
|
||||
|
||||
type Comparator func(a, b interface{}) int
|
||||
|
||||
//比较器的特种——相等器
|
||||
//判断传入的两个元素是否相等
|
||||
type Equaler func(a, b interface{}) (B bool)
|
||||
|
||||
//@title GetCmp
|
||||
//@description
|
||||
// 传入一个数据并根据该数据类型返回一个对应的比较器
|
||||
// 若该类型并非系统自带类型,则返回个空比较器
|
||||
// 若传入元素为nil则之间返回nil
|
||||
//@receiver nil
|
||||
//@param e interface{}
|
||||
//@return cmp Comparator 该类型对应的默认比较器
|
||||
func GetCmp(e interface{}) (cmp Comparator) {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
switch e.(type) {
|
||||
case bool:
|
||||
return boolCmp
|
||||
case int:
|
||||
return intCmp
|
||||
case int8:
|
||||
return int8Cmp
|
||||
case uint8:
|
||||
return uint8Cmp
|
||||
case int16:
|
||||
return int16Cmp
|
||||
case uint16:
|
||||
return uint16Cmp
|
||||
case int32:
|
||||
return int32Cmp
|
||||
case uint32:
|
||||
return uint32Cmp
|
||||
case int64:
|
||||
return int64Cmp
|
||||
case uint64:
|
||||
return uint64Cmp
|
||||
case float32:
|
||||
return float32Cmp
|
||||
case float64:
|
||||
return float64Cmp
|
||||
case complex64:
|
||||
return complex64Cmp
|
||||
case complex128:
|
||||
return complex128Cmp
|
||||
case string:
|
||||
return stringCmp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//@title GetEqual
|
||||
//@description
|
||||
// 传入一个数据并根据该数据类型返回一个对应的比较器
|
||||
// 若该类型并非系统自带类型,则返回个空比较器
|
||||
// 若传入元素为nil则之间返回nil
|
||||
//@receiver nil
|
||||
//@param e interface{}
|
||||
//@return cmp Comparator 该类型对应的默认比较器
|
||||
func GetEqual() (equ Equaler) {
|
||||
return basicEqual
|
||||
}
|
||||
|
||||
//@title basicEqual
|
||||
//@description
|
||||
// 返回基本比较器
|
||||
// 即有且仅有判断量元素是否完全相等
|
||||
//@receiver a interface{} 待判断相等的第一个元素
|
||||
//@receiver b interface{} 待判断相等的第二个元素
|
||||
//@param nil
|
||||
//@return B bool 这两个元素是否相等?
|
||||
func basicEqual(a, b interface{}) (B bool) {
|
||||
return a == b
|
||||
}
|
||||
|
||||
//以下为系统自带类型的默认比较器
|
||||
|
||||
func boolCmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(bool) {
|
||||
return 1
|
||||
} else if b.(bool) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func intCmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(int) > b.(int) {
|
||||
return 1
|
||||
} else if a.(int) < b.(int) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func int8Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(int8) > b.(int8) {
|
||||
return 1
|
||||
} else if a.(int8) < b.(int8) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func uint8Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(uint8) > b.(uint8) {
|
||||
return 1
|
||||
} else if a.(uint8) < b.(uint8) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func int16Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(int16) > b.(int16) {
|
||||
return 1
|
||||
} else if a.(int16) < b.(int16) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func uint16Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(uint16) > b.(uint16) {
|
||||
return 1
|
||||
} else if a.(uint16) < b.(uint16) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func int32Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(int32) > b.(int32) {
|
||||
return 1
|
||||
} else if a.(int32) < b.(int32) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func uint32Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(uint32) > b.(uint32) {
|
||||
return 1
|
||||
} else if a.(uint32) < b.(uint32) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func int64Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(int64) > b.(int64) {
|
||||
return 1
|
||||
} else if a.(int64) < b.(int64) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func uint64Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(uint64) > b.(uint64) {
|
||||
return 1
|
||||
} else if a.(uint64) < b.(uint64) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func float32Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(float32) > b.(float32) {
|
||||
return 1
|
||||
} else if a.(float32) < b.(float32) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func float64Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if a.(float64) > b.(float64) {
|
||||
return 1
|
||||
} else if a.(float64) < b.(float64) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func complex64Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if real(a.(complex64)) > real(b.(complex64)) {
|
||||
return 1
|
||||
} else if real(a.(complex64)) < real(b.(complex64)) {
|
||||
return -1
|
||||
} else {
|
||||
if imag(a.(complex64)) > imag(b.(complex64)) {
|
||||
return 1
|
||||
} else if imag(a.(complex64)) < imag(b.(complex64)) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func complex128Cmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if real(a.(complex128)) > real(b.(complex128)) {
|
||||
return 1
|
||||
} else if real(a.(complex128)) < real(b.(complex128)) {
|
||||
return -1
|
||||
} else {
|
||||
if imag(a.(complex128)) > imag(b.(complex128)) {
|
||||
return 1
|
||||
} else if imag(a.(complex128)) < imag(b.(complex128)) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func stringCmp(a, b interface{}) int {
|
||||
if a == b {
|
||||
return 0
|
||||
}
|
||||
if len(a.(string)) > len(b.(string)) {
|
||||
return 1
|
||||
} else if len(a.(string)) < len(b.(string)) {
|
||||
return -1
|
||||
} else {
|
||||
if a.(string) > b.(string) {
|
||||
return 1
|
||||
} else if a.(string) < b.(string) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
79
utils/comparator/nth_element.go
Normal file
79
utils/comparator/nth_element.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package comparator
|
||||
|
||||
//@Title comparator
|
||||
//@Description
|
||||
// 该包内通过利用比较函数重排传入的数组,使得下标为n的元素必然是第n+1大的(考虑到下标从0开始)
|
||||
// 对二分排序的变形,当只对该节点位置存在的某一局部进行查找即可
|
||||
|
||||
//@title NthElement
|
||||
//@description
|
||||
// 若数组指针为nil或者数组为nil或数组长度为0则直接结束即可
|
||||
// 通过利用比较函数重排传入的数组,使得下标为n的元素必然是第n+1大的(考虑到下标从0开始)
|
||||
// 若n大于数组长度,直接结束,否则对第n+1大的元素排序后返回该元素
|
||||
//@receiver nil
|
||||
//@param begin *[]interface{} 待查找的元素数组指针
|
||||
//@param n int 待查找的是第n位,从0计数
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return value interface{} 第n+1大的元素
|
||||
func NthElement(arr *[]interface{}, n int, Cmp ...Comparator) (value interface{}){
|
||||
if arr==nil || (*arr)==nil || len((*arr)) == 0 {
|
||||
return nil
|
||||
}
|
||||
//判断比较函数是否有效
|
||||
var cmp Comparator
|
||||
cmp = nil
|
||||
if len(Cmp) > 0 {
|
||||
cmp = Cmp[0]
|
||||
} else {
|
||||
cmp = GetCmp((*arr)[0])
|
||||
}
|
||||
if cmp == nil {
|
||||
return nil
|
||||
}
|
||||
//判断待确认的第n位是否在该集合范围内
|
||||
if len((*arr)) < n || n<0 {
|
||||
return nil
|
||||
}
|
||||
//进行查找
|
||||
nthElement(arr,0,len((*arr))-1, n, cmp)
|
||||
return (*arr)[n]
|
||||
}
|
||||
|
||||
//@title nthElement
|
||||
//@description
|
||||
// 对传入的开启和结尾的两个比较器中的值进行查找
|
||||
// 以传入的比较器进行比较
|
||||
// 通过局部二分的方式进行查找并将第n小的元素放到第n位置(大小按比较器进行确认,默认未小)
|
||||
//@receiver nil
|
||||
//@param begin *[]interface{} 待查找的元素数组指针
|
||||
//@param l int 查找范围的左下标
|
||||
//@param r int 查找范围的右下标
|
||||
//@param n int 待查找的是第n位,从0计数
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
func nthElement(arr *[]interface{},l,r int, n int, cmp Comparator){
|
||||
//二分该区域并对此进行预排序
|
||||
if l >= r {
|
||||
return
|
||||
}
|
||||
m := (*arr)[(r + l) / 2]
|
||||
i, j := l-1, r+1
|
||||
for i < j {
|
||||
i++
|
||||
for cmp((*arr)[i], m) < 0 {
|
||||
i++
|
||||
}
|
||||
j--
|
||||
for cmp((*arr)[j], m) > 0 {
|
||||
j--
|
||||
}
|
||||
if i < j {
|
||||
(*arr)[i],(*arr)[j]=(*arr)[j],(*arr)[i]
|
||||
}
|
||||
}
|
||||
//确认第n位的范围进行局部二分
|
||||
if n-1 >= i {
|
||||
nthElement(arr,j+1,r, n, cmp)
|
||||
} else {
|
||||
nthElement(arr,l,j, n, cmp)
|
||||
}
|
||||
}
|
68
utils/comparator/search.go
Normal file
68
utils/comparator/search.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package comparator
|
||||
|
||||
//@Title comparator
|
||||
//@Description
|
||||
// 该部分为对带查找数组中元素进行二分查找
|
||||
// warning:仅对有序元素集合有效
|
||||
|
||||
//@title Search
|
||||
//@description
|
||||
// 若数组指针为nil或者数组为nil或数组长度为0则直接结束即可
|
||||
// 通过比较函数对传入的数组中的元素集合进行二分查找
|
||||
// 若并未传入比较函数则寻找默认比较函数
|
||||
// 找到后返回该元素的下标
|
||||
// 若该元素不在该部分内存在,则返回-1
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待查找的有序数组
|
||||
//@param e interface{} 待查找元素
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return idx int 待查找元素下标
|
||||
func Search(arr *[]interface{}, e interface{}, Cmp ...Comparator) (idx int) {
|
||||
if arr==nil || (*arr)==nil || len((*arr)) == 0 {
|
||||
return
|
||||
}
|
||||
//判断比较函数是否有效,若无效则寻找默认比较函数
|
||||
var cmp Comparator
|
||||
cmp = nil
|
||||
if len(Cmp) == 0 {
|
||||
cmp = GetCmp(e)
|
||||
} else {
|
||||
cmp = Cmp[0]
|
||||
}
|
||||
if cmp == nil {
|
||||
//若并非默认类型且未传入比较器则直接结束
|
||||
return -1
|
||||
}
|
||||
//查找开始
|
||||
return search(arr, e, cmp)
|
||||
}
|
||||
|
||||
//@title search
|
||||
//@description
|
||||
// 通过比较函数对传入的数组中的元素集合进行二分查找
|
||||
// 找到后返回该元素的下标
|
||||
// 若该元素不在该部分内存在,则返回-1
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待查找的有序数组
|
||||
//@param e interface{} 待查找元素
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return idx int 待查找元素下标
|
||||
func search(arr *[]interface{}, e interface{}, cmp Comparator) (idx int) {
|
||||
//通过二分查找的方式寻找该元素
|
||||
l, m, r := 0, (len((*arr))-1)/2, len((*arr))
|
||||
for l < r {
|
||||
m = (l + r) / 2
|
||||
if cmp((*arr)[m], e) < 0 {
|
||||
l = m + 1
|
||||
} else {
|
||||
r = m
|
||||
}
|
||||
}
|
||||
//查找结束
|
||||
if (*arr)[l] == e {
|
||||
//该元素存在,返回下标
|
||||
return l
|
||||
}
|
||||
//该元素不存在,返回-1
|
||||
return -1
|
||||
}
|
123
utils/comparator/sort.go
Normal file
123
utils/comparator/sort.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package comparator
|
||||
|
||||
//@Title comparator
|
||||
//@Description
|
||||
// 该包内通过待比较数组和比较函数进行排序
|
||||
// 当前支持二分排序和归并排序
|
||||
|
||||
|
||||
//@title Sort
|
||||
//@description
|
||||
// 若数组指针为nil或者数组为nil或数组长度为0则直接结束即可
|
||||
// 对传入的数组进行通过比较函数进行比较
|
||||
// 若未传入比较函数则寻找默认比较器,默认比较器排序结果为升序
|
||||
// 若该泛型类型并非系统默认类型之一,则不进行排序
|
||||
// 当待排序元素个数超过2^16个时使用归并排序
|
||||
// 当待排序元素个数少于2^16个时使用二分排序
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待排序数组的指针
|
||||
//@param Cmp ...Comparator 比较函数
|
||||
//@return nil
|
||||
func Sort(arr *[]interface{}, Cmp ...Comparator) {
|
||||
//如果传入一个空数组或nil,则直接结束
|
||||
if arr==nil || (*arr)==nil || len((*arr)) == 0 {
|
||||
return
|
||||
}
|
||||
var cmp Comparator
|
||||
cmp = nil
|
||||
if len(Cmp) > 0 {
|
||||
cmp = Cmp[0]
|
||||
} else {
|
||||
cmp = GetCmp((*arr)[0])
|
||||
}
|
||||
if cmp == nil {
|
||||
//未传入比较器且并非默认类型导致未找到默认比较器则直接终止排序
|
||||
return
|
||||
}
|
||||
//根据数组长度进行分类选择排序函数
|
||||
if len((*arr)) < 2^26 {
|
||||
//当长度小于2^16时使用二分排序
|
||||
binary(arr,0,len((*arr))-1, cmp)
|
||||
} else {
|
||||
merge(arr,0,len((*arr))-1, cmp)
|
||||
}
|
||||
}
|
||||
|
||||
//@title binary
|
||||
//@description
|
||||
// 二分排序
|
||||
// 对传入的待比较数组中的元素使用比较函数进行二分排序
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待排序数组指针
|
||||
//@param l int 待排序数组的左下标
|
||||
//@param r int 待排序数组的右下标
|
||||
//@param cmp Comparator 比较函数
|
||||
//@return nil
|
||||
func binary(arr *[]interface{},l,r int, cmp Comparator) {
|
||||
//对当前部分进行预排序,使得两侧都大于或小于中间值
|
||||
if l >= r {
|
||||
return
|
||||
}
|
||||
m := (*arr)[(r + l) / 2]
|
||||
i, j := l-1, r+1
|
||||
for i < j {
|
||||
i++
|
||||
for cmp((*arr)[i], m) < 0 {
|
||||
i++
|
||||
}
|
||||
j--
|
||||
for cmp((*arr)[j],m) > 0 {
|
||||
j--
|
||||
}
|
||||
if i < j {
|
||||
(*arr)[i],(*arr)[j]=(*arr)[j],(*arr)[i]
|
||||
}
|
||||
}
|
||||
//对分好的两侧进行迭代二分排序
|
||||
binary(arr,l,j, cmp)
|
||||
binary(arr,j+1,r, cmp)
|
||||
}
|
||||
|
||||
//@title merge
|
||||
//@description
|
||||
// 归并排序
|
||||
// 对传入的两个迭代器中的内容使用比较器进行归并排序
|
||||
//@receiver nil
|
||||
//@param arr *[]interface{} 待排序数组指针
|
||||
//@param l int 待排序数组的左下标
|
||||
//@param r int 待排序数组的右下标
|
||||
//@param cmp Comparator 比较函数
|
||||
//@return nil
|
||||
func merge(arr *[]interface{},l,r int, cmp Comparator) {
|
||||
//对当前部分进行分组排序,将该部分近似平均的拆为两部分进行比较排序
|
||||
if l >= r {
|
||||
return
|
||||
}
|
||||
m := (r + l) / 2
|
||||
//对待排序内容进行二分
|
||||
merge(arr,l,m, cmp)
|
||||
merge(arr,m+1,r, cmp)
|
||||
//二分结束后依次比较进行归并
|
||||
i, j := l, m+1
|
||||
var tmp []interface{}=make([]interface{},0,r-l+1)
|
||||
for i <= m && j <= r {
|
||||
if cmp((*arr)[i], (*arr)[j]) <= 0 {
|
||||
tmp = append(tmp, (*arr)[i])
|
||||
i++
|
||||
} else {
|
||||
tmp = append(tmp, (*arr)[j])
|
||||
j++
|
||||
}
|
||||
}
|
||||
//当一方比较到头时将另一方剩余内容全部加入进去
|
||||
for ; i <= m; i++ {
|
||||
tmp = append(tmp, (*arr)[i])
|
||||
}
|
||||
for ; j <= r; j++ {
|
||||
tmp = append(tmp, (*arr)[j])
|
||||
}
|
||||
//将局部排序结果放入迭代器中
|
||||
for i, j = l, 0; i <= r; i, j = i+1, j+1 {
|
||||
(*arr)[i]=tmp[j]
|
||||
}
|
||||
}
|
305
utils/iterator/Iterator.go
Normal file
305
utils/iterator/Iterator.go
Normal file
@@ -0,0 +1,305 @@
|
||||
package Iterator
|
||||
|
||||
//@Title Iterator
|
||||
//@Description
|
||||
// 迭代器
|
||||
// 定义了一套迭代器接口和迭代器类型
|
||||
// 本套接口定义了迭代器所要执行的基本函数
|
||||
// 数据结构在使用迭代器时需要重写函数
|
||||
// 其中主要包括:生成迭代器,移动迭代器,判断是否可移动
|
||||
|
||||
//Iterator迭代器
|
||||
//包含泛型切片和该迭代器当前指向元素的下标
|
||||
//可通过下标和泛型切片长度来判断是否可以前移或后移
|
||||
//当index不小于0时迭代器可前移
|
||||
//当index小于data的长度时可后移
|
||||
type Iterator struct {
|
||||
data *[]interface{} //该迭代器中存放的元素集合的指针
|
||||
index int //该迭代器当前指向的元素下标,-1即不存在元素
|
||||
}
|
||||
|
||||
//Iterator迭代器接口
|
||||
//定义了一套迭代器接口函数
|
||||
//函数含义详情见下列描述
|
||||
type Iteratorer interface {
|
||||
Begin() (I *Iterator) //将该迭代器设为位于首节点并返回新迭代器
|
||||
End() (I *Iterator) //将该迭代器设为位于尾节点并返回新迭代器
|
||||
Get(idx int) (I *Iterator) //将该迭代器设为位于第idx节点并返回该迭代器
|
||||
Value() (e interface{}) //返回该迭代器下标所指元素
|
||||
HasNext() (b bool) //判断该迭代器是否可以后移
|
||||
Next() (b bool) //将该迭代器后移一位
|
||||
HasPre() (b bool) //判罚该迭代器是否可以前移
|
||||
Pre() (b bool) //将该迭代器前移一位
|
||||
}
|
||||
|
||||
//@title New
|
||||
//@description
|
||||
// 新建一个Iterator迭代器容器并返回
|
||||
// 传入的切片指针设为迭代器所承载的元素集合
|
||||
// 若传入下标,则将传入的第一个下标设为该迭代器当前指向下标
|
||||
// 若该下标超过元素集合范围,则寻找最近的下标
|
||||
// 若元素集合为空,则下标设为-1
|
||||
//@receiver nil
|
||||
//@param data *[]interface{} 迭代器所承载的元素集合的指针
|
||||
//@param Idx ...int 预设的迭代器的下标
|
||||
//@return i *Iterator 新建的Iterator迭代器指针
|
||||
func New(data *[]interface{}, Idx ...int) (i *Iterator) {
|
||||
//迭代器下标
|
||||
var idx int
|
||||
if len(Idx) <= 0 {
|
||||
//没有传入下标,则将下标设为0
|
||||
idx = 0
|
||||
} else {
|
||||
//有传入下标,则将传入下标第一个设为迭代器下标
|
||||
idx = Idx[0]
|
||||
}
|
||||
if len((*data)) > 0 {
|
||||
//如果元素集合非空,则判断下标是否超过元素集合范围
|
||||
if idx >= len((*data)) {
|
||||
//如果传入下标超过元素集合范围则寻找最近的下标值
|
||||
idx = len((*data)) - 1
|
||||
}
|
||||
} else {
|
||||
//如果元素集合为空则将下标设为-1
|
||||
idx = -1
|
||||
}
|
||||
//新建并返回迭代器
|
||||
return &Iterator{
|
||||
data: data,
|
||||
index: idx,
|
||||
}
|
||||
}
|
||||
|
||||
//@title Begin
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 如果迭代器为空,直接结束
|
||||
// 如果该迭代器元素集合为空,则将下标设为-1
|
||||
// 如果该迭代器元素集合不为空,则将下标设为0
|
||||
// 随后返回新迭代器指针
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param nil
|
||||
//@return I *Iterator 修改后的新迭代器指针
|
||||
func (i *Iterator) Begin() (I *Iterator) {
|
||||
if i == nil {
|
||||
//迭代器为空,直接结束
|
||||
return nil
|
||||
}
|
||||
if len((*i.data)) == 0 {
|
||||
//迭代器元素集合为空,下标设为-1
|
||||
i.index = -1
|
||||
} else {
|
||||
//迭代器元素集合非空,下标设为0
|
||||
i.index = 0
|
||||
}
|
||||
//返回修改后的新指针
|
||||
return &Iterator{
|
||||
data: i.data,
|
||||
index: i.index,
|
||||
}
|
||||
}
|
||||
|
||||
//@title End
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 如果迭代器为空,直接结束
|
||||
// 如果该迭代器元素集合为空,则将下标设为-1
|
||||
// 如果该迭代器元素集合不为空,则将下标设为元素集合的最后一个元素的下标
|
||||
// 随后返回新迭代器指针
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param nil
|
||||
//@return I *Iterator 修改后的新迭代器指针
|
||||
func (i *Iterator) End() (I *Iterator) {
|
||||
if i == nil {
|
||||
//迭代器为空,直接返回
|
||||
return nil
|
||||
}
|
||||
if len((*i.data)) == 0 {
|
||||
//元素集合为空,下标设为-1
|
||||
i.index = -1
|
||||
} else {
|
||||
//元素集合非空,下标设为最后一个元素的下标
|
||||
i.index = len((*i.data)) - 1
|
||||
}
|
||||
//返回修改后的该指针
|
||||
return &Iterator{
|
||||
data: i.data,
|
||||
index: i.index,
|
||||
}
|
||||
}
|
||||
|
||||
//@title Get
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 如果迭代器为空,直接结束
|
||||
// 如果该迭代器元素集合为空,则将下标设为-1
|
||||
// 如果该迭代器元素集合不为空,则将下标设为传入的预设下标
|
||||
// 如果预设下标超过元素集合范围,则将下标设为最近元素的下标
|
||||
// 随后返回该迭代器指针
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param idx int 预设下标
|
||||
//@return I *Iterator 修改后的该迭代器指针
|
||||
func (i *Iterator) Get(idx int) (I *Iterator) {
|
||||
if i == nil {
|
||||
//迭代器为空,直接返回
|
||||
return nil
|
||||
}
|
||||
if idx <= 0 {
|
||||
//预设下标超过元素集合范围,将下标设为最近元素的下标,此状态下为首元素下标
|
||||
idx = 0
|
||||
} else if idx >= len((*i.data))-1 {
|
||||
//预设下标超过元素集合范围,将下标设为最近元素的下标,此状态下为尾元素下标
|
||||
idx = len((*i.data)) - 1
|
||||
}
|
||||
if len((*i.data)) > 0 {
|
||||
//元素集合非空,迭代器下标设为预设下标
|
||||
i.index = idx
|
||||
} else {
|
||||
//元素集合为空,迭代器下标设为-1
|
||||
i.index = -1
|
||||
}
|
||||
//返回修改后的迭代器指针
|
||||
return i
|
||||
}
|
||||
|
||||
//@title Value
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 返回迭代器当前下标所指元素
|
||||
// 若迭代器为nil或元素集合为空,返回nil
|
||||
// 否则返回迭代器当前下标所指向的元素
|
||||
// 如果该下标超过元素集合范围,则返回距离最近的元素
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param nil
|
||||
//@return e interface{} 迭代器下标所指元素
|
||||
func (i *Iterator) Value() (e interface{}) {
|
||||
if i == nil {
|
||||
//迭代器为nil,返回nil
|
||||
return nil
|
||||
}
|
||||
if len((*i.data)) == 0 {
|
||||
//元素集合为空,返回nil
|
||||
return nil
|
||||
}
|
||||
if i.index <= 0 {
|
||||
//下标超过元素集合范围下限,最近元素为首元素
|
||||
i.index = 0
|
||||
}
|
||||
if i.index >= len((*i.data)) {
|
||||
//下标超过元素集合范围上限,最近元素为尾元素
|
||||
i.index = len((*i.data)) - 1
|
||||
}
|
||||
//返回下标指向元素
|
||||
return (*i.data)[i.index]
|
||||
}
|
||||
|
||||
//@title HasNext
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 判断该迭代器是否可以后移
|
||||
// 当迭代器为nil时不能后移
|
||||
// 当元素集合为空时不能后移
|
||||
// 当下标到达元素集合范围上限时不能后移
|
||||
// 否则可以后移
|
||||
//@author hlccd 2021-07-1
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param nil
|
||||
//@return b bool 迭代器下标可以后移?
|
||||
func (i *Iterator) HasNext() (b bool) {
|
||||
if i == nil {
|
||||
//迭代器为nil时不能后移
|
||||
return false
|
||||
}
|
||||
if len((*i.data)) == 0 {
|
||||
//元素集合为空时不能后移
|
||||
return false
|
||||
}
|
||||
//下标到达元素集合上限时不能后移,否则可以后移
|
||||
return i.index < len((*i.data))
|
||||
}
|
||||
|
||||
//@title Next
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 将迭代器下标后移
|
||||
// 当满足后移条件时进行后移同时返回true
|
||||
// 当不满足后移条件时将下标设为尾元素下标同时返回false
|
||||
// 当迭代器为nil时返回false
|
||||
// 当元素集合为空时下标设为-1同时返回false
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param nil
|
||||
//@return b bool 迭代器下标后移成功?
|
||||
func (i *Iterator) Next() (b bool) {
|
||||
if i == nil {
|
||||
//迭代器为nil时返回false
|
||||
return false
|
||||
}
|
||||
if i.HasNext() {
|
||||
//满足后移条件时进行后移
|
||||
i.index++
|
||||
return true
|
||||
}
|
||||
if len((*i.data)) == 0 {
|
||||
//元素集合为空时下标设为-1同时返回false
|
||||
i.index = -1
|
||||
return false
|
||||
}
|
||||
//不满足后移条件时将下标设为尾元素下标并返回false
|
||||
i.index = len((*i.data)) - 1
|
||||
return false
|
||||
}
|
||||
|
||||
//@title HasPre
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 判断该迭代器是否可以前移
|
||||
// 当迭代器为nil时不能前移
|
||||
// 当元素集合为空时不能前移
|
||||
// 当下标到达元素集合范围下限时不能前移
|
||||
// 否则可以前移
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param nil
|
||||
//@return b bool 迭代器下标可以前移?
|
||||
func (i *Iterator) HasPre() (b bool) {
|
||||
if i == nil {
|
||||
//迭代器为nil时不能前移
|
||||
return false
|
||||
}
|
||||
if len((*i.data)) == 0 {
|
||||
//元素集合为空时不能前移
|
||||
return false
|
||||
}
|
||||
//下标到达元素集合范围下限时不能前移,否则可以后移
|
||||
return i.index >= 0
|
||||
}
|
||||
|
||||
//@title Pre
|
||||
//@description
|
||||
// 以Iterator迭代器指针做接收者
|
||||
// 将迭代器下标前移
|
||||
// 当满足前移条件时进行前移同时返回true
|
||||
// 当不满足前移条件时将下标设为首元素下标同时返回false
|
||||
// 当迭代器为nil时返回false
|
||||
// 当元素集合为空时下标设为-1同时返回false
|
||||
//@receiver i *Iterator 迭代器指针
|
||||
//@param nil
|
||||
//@return b bool 迭代器下标前移成功?
|
||||
func (i *Iterator) Pre() (b bool) {
|
||||
if i == nil {
|
||||
//迭代器为nil时返回false
|
||||
return false
|
||||
}
|
||||
if i.HasPre() {
|
||||
//满足后移条件时进行前移
|
||||
i.index--
|
||||
return true
|
||||
}
|
||||
if len((*i.data)) == 0 {
|
||||
//元素集合为空时下标设为-1同时返回false
|
||||
i.index = -1
|
||||
return false
|
||||
}
|
||||
//不满足后移条件时将下标设为尾元素下标并返回false
|
||||
i.index = 0
|
||||
return false
|
||||
}
|
Reference in New Issue
Block a user