mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
update: update Enqueue and Dequeue
This commit is contained in:
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// ArrayQueue implements queue with slice
|
// ArrayQueue implements queue with slice
|
||||||
type ArrayQueue[T any] struct {
|
type ArrayQueue[T any] struct {
|
||||||
items []T
|
data []T
|
||||||
head int
|
head int
|
||||||
tail int
|
tail int
|
||||||
capacity int
|
capacity int
|
||||||
@@ -21,7 +21,7 @@ type ArrayQueue[T any] struct {
|
|||||||
|
|
||||||
func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
|
func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
|
||||||
return &ArrayQueue[T]{
|
return &ArrayQueue[T]{
|
||||||
items: make([]T, 0, capacity),
|
data: make([]T, 0, capacity),
|
||||||
head: 0,
|
head: 0,
|
||||||
tail: 0,
|
tail: 0,
|
||||||
capacity: capacity,
|
capacity: capacity,
|
||||||
@@ -33,7 +33,7 @@ func NewArrayQueue[T any](capacity int) *ArrayQueue[T] {
|
|||||||
func (q *ArrayQueue[T]) Data() []T {
|
func (q *ArrayQueue[T]) Data() []T {
|
||||||
items := []T{}
|
items := []T{}
|
||||||
for i := q.head; i < q.tail; i++ {
|
for i := q.head; i < q.tail; i++ {
|
||||||
items = append(items, q.items[i])
|
items = append(items, q.data[i])
|
||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
@@ -55,40 +55,71 @@ func (q *ArrayQueue[T]) IsFull() bool {
|
|||||||
|
|
||||||
// Front return front value of queue
|
// Front return front value of queue
|
||||||
func (q *ArrayQueue[T]) Front() T {
|
func (q *ArrayQueue[T]) Front() T {
|
||||||
return q.items[0]
|
return q.data[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back return back value of queue
|
// Back return back value of queue
|
||||||
func (q *ArrayQueue[T]) Back() T {
|
func (q *ArrayQueue[T]) Back() T {
|
||||||
return q.items[q.size-1]
|
return q.data[q.size-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnQueue put element into queue
|
// EnQueue put element into queue
|
||||||
func (q *ArrayQueue[T]) Enqueue(item T) bool {
|
func (q *ArrayQueue[T]) Enqueue(item T) bool {
|
||||||
if q.head == 0 && q.tail == q.capacity {
|
if q.tail < q.capacity {
|
||||||
return false
|
q.data = append(q.data, item)
|
||||||
} else if q.head != 0 && q.tail == q.capacity {
|
// q.tail++
|
||||||
for i := q.head; i < q.tail; i++ {
|
q.data[q.tail] = item
|
||||||
q.items[i-q.head] = q.items[i]
|
} else {
|
||||||
|
//upgrade
|
||||||
|
if q.head > 0 {
|
||||||
|
for i := 0; i < q.tail-q.head; i++ {
|
||||||
|
q.data[i] = q.data[i+q.head]
|
||||||
|
}
|
||||||
|
q.tail -= q.head
|
||||||
|
q.head = 0
|
||||||
|
} else {
|
||||||
|
if q.capacity < 65536 {
|
||||||
|
if q.capacity == 0 {
|
||||||
|
q.capacity = 1
|
||||||
|
}
|
||||||
|
q.capacity *= 2
|
||||||
|
} else {
|
||||||
|
q.capacity += 2 ^ 16
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := make([]T, q.capacity, q.capacity)
|
||||||
|
copy(tmp, q.data)
|
||||||
|
q.data = tmp
|
||||||
}
|
}
|
||||||
q.tail = q.tail - q.head
|
|
||||||
q.head = 0
|
q.data[q.tail] = item
|
||||||
}
|
}
|
||||||
|
|
||||||
q.items = append(q.items, item)
|
|
||||||
q.tail++
|
q.tail++
|
||||||
q.size++
|
q.size++
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
|
// DeQueue remove head element of queue and return it, if queue is empty, return nil and error
|
||||||
func (q *ArrayQueue[T]) Dequeue() (T, bool) {
|
func (q *ArrayQueue[T]) Dequeue() (T, bool) {
|
||||||
var item T
|
var item T
|
||||||
if q.head == q.tail {
|
if q.size == 0 {
|
||||||
return item, false
|
return item, false
|
||||||
}
|
}
|
||||||
item = q.items[q.head]
|
|
||||||
|
item = q.data[q.head]
|
||||||
q.head++
|
q.head++
|
||||||
|
|
||||||
|
if q.head >= 1024 || q.head*2 > q.tail {
|
||||||
|
q.capacity -= q.head
|
||||||
|
q.tail -= q.head
|
||||||
|
tmp := make([]T, q.capacity, q.capacity)
|
||||||
|
copy(tmp, q.data[q.head:])
|
||||||
|
q.data = tmp
|
||||||
|
q.head = 0
|
||||||
|
}
|
||||||
|
|
||||||
q.size--
|
q.size--
|
||||||
return item, true
|
return item, true
|
||||||
}
|
}
|
||||||
@@ -96,7 +127,7 @@ func (q *ArrayQueue[T]) Dequeue() (T, bool) {
|
|||||||
// Clear the queue data
|
// Clear the queue data
|
||||||
func (q *ArrayQueue[T]) Clear() {
|
func (q *ArrayQueue[T]) Clear() {
|
||||||
capacity := q.capacity
|
capacity := q.capacity
|
||||||
q.items = make([]T, 0, capacity)
|
q.data = make([]T, 0, capacity)
|
||||||
q.head = 0
|
q.head = 0
|
||||||
q.tail = 0
|
q.tail = 0
|
||||||
q.size = 0
|
q.size = 0
|
||||||
@@ -105,7 +136,7 @@ func (q *ArrayQueue[T]) Clear() {
|
|||||||
|
|
||||||
// Contain checks if the value is in queue or not
|
// Contain checks if the value is in queue or not
|
||||||
func (q *ArrayQueue[T]) Contain(value T) bool {
|
func (q *ArrayQueue[T]) Contain(value T) bool {
|
||||||
for _, v := range q.items {
|
for _, v := range q.data {
|
||||||
if reflect.DeepEqual(v, value) {
|
if reflect.DeepEqual(v, value) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -117,7 +148,7 @@ func (q *ArrayQueue[T]) Contain(value T) bool {
|
|||||||
func (q *ArrayQueue[T]) Print() {
|
func (q *ArrayQueue[T]) Print() {
|
||||||
info := "["
|
info := "["
|
||||||
for i := q.head; i < q.tail; i++ {
|
for i := q.head; i < q.tail; i++ {
|
||||||
info += fmt.Sprintf("%+v, ", q.items[i])
|
info += fmt.Sprintf("%+v, ", q.data[i])
|
||||||
}
|
}
|
||||||
info += "]"
|
info += "]"
|
||||||
fmt.Println(info)
|
fmt.Println(info)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ func TestArrayQueue_Enqueue(t *testing.T) {
|
|||||||
|
|
||||||
assert := internal.NewAssert(t, "TestArrayQueue_Enqueue")
|
assert := internal.NewAssert(t, "TestArrayQueue_Enqueue")
|
||||||
|
|
||||||
queue := NewArrayQueue[int](5)
|
queue := NewArrayQueue[int](2)
|
||||||
queue.Enqueue(1)
|
queue.Enqueue(1)
|
||||||
queue.Enqueue(2)
|
queue.Enqueue(2)
|
||||||
queue.Enqueue(3)
|
queue.Enqueue(3)
|
||||||
|
|||||||
Reference in New Issue
Block a user