refactor: rewrite arrayqueue

This commit is contained in:
dudaodong
2022-04-08 17:39:54 +08:00
parent 20b9e5353e
commit 5483380066
2 changed files with 85 additions and 51 deletions

View File

@@ -1,79 +1,101 @@
package datastructure
import (
"errors"
"fmt"
"reflect"
)
// ArrayQueue implements queue with slice
type ArrayQueue[T any] struct {
data []T
length int
items []T
head int
tail int
capacity int
size int
}
// NewArrayQueue return a empty ArrayQueue pointer
func NewArrayQueue[T any](values ...T) *ArrayQueue[T] {
data := make([]T, len(values))
for i, v := range values {
data[i] = v
func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
return &ArrayQueue[T]{
items: make([]T, 0, capacity),
head: 0,
tail: 0,
capacity: capacity,
size: 0,
}
return &ArrayQueue[T]{data: data, length: len(values)}
}
// Data return queue data
func (q *ArrayQueue[T]) Data() []T {
return q.data
items := []T{}
for i := q.head; i < q.tail; i++ {
items = append(items, q.items[i])
}
return items
}
// Size return length of queue data
func (q *ArrayQueue[T]) Size() int {
return q.length
return q.size
}
// IsEmpty checks if queue is empty or not
func (q *ArrayQueue[T]) IsEmpty() bool {
return q.length == 0
return q.size == 0
}
// Front return front value of queue
func (q *ArrayQueue[T]) Front() T {
return q.data[0]
return q.items[0]
}
// Back return back value of queue
func (q *ArrayQueue[T]) Back() T {
return q.data[q.length-1]
return q.items[q.size-1]
}
// EnQueue put element into queue
func (q *ArrayQueue[T]) EnQueue(value T) {
q.data = append(q.data, value)
q.length++
func (q *ArrayQueue[T]) Enqueue(item T) bool {
if q.head == 0 && q.tail == q.capacity {
return false
} else if q.head != 0 && q.tail == q.capacity {
for i := q.head; i < q.tail; i++ {
q.items[i-q.head] = q.items[i]
}
q.tail = q.tail - q.head
q.head = 0
}
q.items = append(q.items, item)
q.tail++
q.size++
return true
}
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
func (q *ArrayQueue[T]) DeQueue() (*T, error) {
if q.IsEmpty() {
return nil, errors.New("queue is empty")
func (q *ArrayQueue[T]) Dequeue() (T, bool) {
var item T
if q.head == q.tail {
return item, false
}
headItem := q.data[0]
q.data = q.data[1:]
q.length--
return &headItem, nil
item = q.items[q.head]
q.head++
q.size--
return item, true
}
// Clear the queue data
func (q *ArrayQueue[T]) Clear() {
q.data = []T{}
q.length = 0
capacity := q.capacity
q.items = make([]T, 0, capacity)
q.head = 0
q.tail = 0
q.size = 0
q.capacity = capacity
}
// Contain checks if the value is in queue or not
func (q *ArrayQueue[T]) Contain(value T) bool {
for _, v := range q.data {
for _, v := range q.items {
if reflect.DeepEqual(v, value) {
return true
}
@@ -84,8 +106,8 @@ func (q *ArrayQueue[T]) Contain(value T) bool {
// Print queue data
func (q *ArrayQueue[T]) Print() {
info := "["
for _, v := range q.data {
info += fmt.Sprintf("%+v, ", v)
for i := q.head; i < q.tail; i++ {
info += fmt.Sprintf("%+v, ", q.items[i])
}
info += "]"
fmt.Println(info)