// Copyright 2021 dudaodong@gmail.com. All rights reserved. // Use of this source code is governed by MIT license // Package datastructure contains some data structure. // Queue structure contains ArrayQueue, LinkedQueue, CircularQueue, and PriorityQueue. package datastructure import ( "errors" "fmt" "reflect" "github.com/duke-git/lancet/v2/datastructure" ) // LinkedQueue implements queue with link list type LinkedQueue[T any] struct { head *datastructure.QueueNode[T] tail *datastructure.QueueNode[T] length int } // NewLinkedQueue return a empty LinkedQueue pointer func NewLinkedQueue[T any]() *LinkedQueue[T] { return &LinkedQueue[T]{head: nil, tail: nil, length: 0} } // Data return slice of queue data func (q *LinkedQueue[T]) Data() []T { res := []T{} current := q.head for current != nil { res = append(res, current.Value) current = current.Next } return res } // Size return length of queue data func (q *LinkedQueue[T]) Size() int { return q.length } // IsEmpty checks if queue is empty or not func (q *LinkedQueue[T]) IsEmpty() bool { return q.length == 0 } // Enqueue put element into queue func (q *LinkedQueue[T]) Enqueue(value T) { newNode := datastructure.NewQueueNode(value) if q.IsEmpty() { q.head = newNode q.tail = newNode } else { q.tail.Next = newNode q.tail = newNode } q.length++ } // Dequeue delete head element of queue then return it, if queue is empty, return nil and error func (q *LinkedQueue[T]) Dequeue() (*T, error) { if q.IsEmpty() { return nil, errors.New("queue is empty") } head := q.head q.head = q.head.Next q.length-- return &head.Value, nil } // Front return front value of queue func (q *LinkedQueue[T]) Front() (*T, error) { if q.IsEmpty() { return nil, errors.New("queue is empty") } return &q.head.Value, nil } // Back return back value of queue func (q *LinkedQueue[T]) Back() (*T, error) { if q.IsEmpty() { return nil, errors.New("queue is empty") } return &q.tail.Value, nil } // Clear clear the queue data func (q *LinkedQueue[T]) Clear() { q.head = nil q.tail = nil q.length = 0 } // Print all nodes info of queue link func (q *LinkedQueue[T]) Print() { current := q.head info := "[ " for current != nil { info += fmt.Sprintf("%+v, ", current) current = current.Next } info += " ]" fmt.Println(info) } // Contain checks if the value is in queue or not func (q *LinkedQueue[T]) Contain(value T) bool { current := q.head for current != nil { if reflect.DeepEqual(current.Value, value) { return true } current = current.Next } return false }