Golang1.18_PriorityQueue

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
}

posted @ 2022-04-20 17:28  月下繁星杨  阅读(89)  评论(0编辑  收藏  举报