PriorityQueue
- 与java的api基本保持一致,也可以使用泛型接口,但最新版的Goland的最新版本对泛型接口的支持有bug,编辑器会爆红,但代码可以正常运行,可以自行扩展接口,实现栈和队列等结构。
代码示例
package main
import (
"DataStruct/src/impl/PriorityQueue"
"fmt"
"sort"
)
func main() {
p1 := &Person{
Name: "java",
Age: 10,
}
p2 := &Person{
Name: "C++",
Age: 19,
}
p3 := &Person{
Name: "Go",
Age: 33,
}
p4 := &Person{
Name: "C#",
Age: 12,
}
p5 := &Person{
Name: "Python",
Age: 22,
}
list := []*Person{p1, p2, p3, p4, p5}
queue := PriorityQueue.New[Person](func(a interface{}, b interface{}) bool {
i := a.(Person)
j := b.(Person)
return i.Age < j.Age
}, 10)
for i := 0; i < 5; i++ {
queue.Add(list[i])
}
array := queue.ToArray()
for i := 0; i < 5; i++ {
fmt.Println(array[i])
}
}
type compare func(interface{}, interface{}) bool
func sortList[T any](list []*T, c compare) []*T {
sort.Slice(list, func(i, j int) bool {
return c(list[i], list[j])
})
return list
}
type Person struct {
Name string
Age int
}
源代码
package PriorityQueue
import (
"reflect"
"sort"
)
const DEFAULT_INITIAL_CAPACITY = 11
const NullPointException = "NullPointerException"
type priorityQueue[T any] struct {
queue []*T
size int
modCount int
length int
sortRule com
}
type com func(a interface{}, b interface{}) bool
func New[T any](compare com, param ...interface{}) *priorityQueue[T] {
p := &priorityQueue[T]{
size: 0,
modCount: 0,
length: 0,
}
l := len(param)
if l == 0 {
p.queue = make([]*T, DEFAULT_INITIAL_CAPACITY)
p.size = DEFAULT_INITIAL_CAPACITY
}
if l > 0 {
p.queue = make([]*T, param[0].(int))
p.size = param[0].(int)
}
p.sortRule = compare
return p
}
func (p *priorityQueue[T]) ensureNonEmpty(q []*T) []*T {
if len(q) > 0 {
return q
} else {
return make([]*T, 1)
}
}
func (p *priorityQueue[T]) Add(e *T) bool {
return p.Offer(e)
}
func (p *priorityQueue[T]) Offer(e *T) bool {
if e == nil {
panic(NullPointException)
}
l := make([]*T, 0)
l = p.queue
if p.length < p.size {
p.queue[p.length] = e
p.length++
} else {
p.queue = append(l, e)
l = p.queue
p.size = len(l)
p.length++
}
p.sort()
return true
}
func (p *priorityQueue[T]) sort() {
array := p.ToArray()
sort.Slice(array, func(i, j int) bool {
return p.sortRule(array[i], array[j])
})
p.transToPointer(array)
}
func (p *priorityQueue[T]) transToPointer(list []T) {
i := len(list)
res := make([]*T, i)
for i := 0; i < len(list); i++ {
res[i] = &list[i]
}
copy(p.queue, res)
}
func (p *priorityQueue[T]) Peek() T {
return *p.queue[0]
}
func (p *priorityQueue[T]) IndexOf(e *T) int {
if e == nil {
panic(NullPointException)
}
l := p.queue
for i := 0; i < p.length; i++ {
if equals(l[i], e) {
return i
}
}
return -1
}
func (p *priorityQueue[T]) Remove(e *T) bool {
i := p.IndexOf(e)
if i == -1 {
return false
} else {
p.RemoveAt(i)
return true
}
}
func (p *priorityQueue[T]) RemoveAt(index int) bool {
temp := make([]*T, 0)
temp = p.queue[index:]
dst := p.queue[index+1:]
copy(temp, dst)
p.length--
return true
}
func (p *priorityQueue[T]) Contains(e *T) bool {
return p.IndexOf(e) >= 0
}
func (p *priorityQueue[T]) ToArray() []T {
res := make([]T, p.length)
for i := 0; i < p.length; i++ {
res[i] = *p.queue[i]
}
return res
}
func (p *priorityQueue[T]) ForEach(f func(e T)) {
for i := 0; i < p.length; i++ {
f(*p.queue[i])
}
}
func (p *priorityQueue[T]) Size() int {
return p.length
}
func equals(a interface{}, b interface{}) bool {
if e, ok := a.(compare); ok {
return e.Equal(b)
} else {
return reflect.DeepEqual(a, b)
}
}
type compare interface {
Equal(object interface{}) bool
}