Unidirectional queue (array implementation)

package main

import (
	"errors"
	"fmt"
	"os"
)

// Queue is an important data structure, which is relatively widely used. There are two main ways to implement queue: array and linked list
// Let's start with a simple one-way queue using arrays
// The queue information includes the size of the queue, the storage form of the queue (array), the head of the queue (not pointing to the first element), and the tail of the queue (pointing to the last element)
// Column operations include adding an element to the queue, fetching an element from the queue, and displaying elements in the queue
// Define a structure to hold the queue information
type signalQueue struct {
	maxSize int
	array [5]int // simulate the queue
	head int
	tail int
}

// Define a method to add elements to the queue
func (q *signalQueue) Push(val int) error{
	// Check whether the queue is full
	if q.tail == q.maxSize - 1 { //tail contains the last element
		return errors.New("Queue full")
	}
	q.tail++ // Move the tail back
	q.array[q.tail] = val
	return nil
}

// Define a method to get elements from the queue
func (q *signalQueue) Pop(a) (val int, err error) {
	// Check whether the queue is empty
	if q.tail == q.head {
		return - 1, errors.New("Queue empty")
	}
	q.head++ // Since the head points in front of the first element, it moves backwards first
	val = q.array[q.head]
	return val, nil
}

// Define a method to display queue elements
func (q *signalQueue) List(a) error {
	// Find the head of the queue (excluding the first element) and walk to the end of the queue
	for i := q.head + 1; i <= q.tail; i++{
		fmt.Printf("array[%d]=%d\t", i, q.array[i])
	}
	fmt.Println()
	return nil
}

func main (a){
	queue := &signalQueue{
		maxSize: 5,
		array:   [5]int{},
		head:    - 1,
		tail:    - 1,}var key string
	var val int
	// Add data
	for {
		fmt.Println("1. Add add data to queue")
		fmt.Println("2. Get gets data from the queue")
		fmt.Println("3.show display queue")
		fmt.Println("4. Exit the queue")

		fmt.Scanln(&key)
		switch key {
		case "add":
			fmt.Println("Enter the data you want to queue.")
			fmt.Scanln(&val)
			err := queue.Push(val)
			iferr ! =nil {
				fmt.Println(err)
			} else {
				fmt.Println("Made the team.")}case "get":
			val, err := queue.Pop()
			iferr ! =nil {
				fmt.Println(err)
			} else {
				fmt.Println("The number of queue exits is:", val)
			}
		case "show":
			queue.List()
		case "exit":
			os.Exit(0)}}}/ / summary:
// One of the biggest problems with the unidirectional queue implemented above is that:
// If there is no valid space for using data, the queue will be displayed as full when adding data, but the queue will be displayed as empty when fetching data
// The solution to this problem is to join the end and head of the array together to create a circular queue
Copy the code

Ring queue (array implementation)

package main

import (
	"errors"
	"fmt"
	"os"
)

// Head refers to the first element in the queue, and tail refers to the next element in the queue.
// Define a structure to manage the ring queue
type circelQueue struct {
	maxSize int
	array [5]int
	head int
	tail int
}

// Define an enqueue method
func (q *circelQueue) Push(val int) error {
	// Check to see if it is full
	if q.IsFull(){
		return errors.New("Queue full")
	}
	q.array[q.tail] = val
	q.tail = (q.tail + 1) % q.maxSize //tail points to the last position of the tail
	return nil
}

// Define an outqueue method
func (q *circelQueue) Pop(a) (val int, err error) {
	// Check whether the queue is empty
	if q.IsEmpty(){
		return - 1, errors.New("Queue empty")
	}
	val = q.array[q.head]
	q.head = (q.head + 1) % q.maxSize //head points to the next element (next team leader)
	return val, nil
}

// Define a method to determine if the ring queue is full
func (q *circelQueue) IsFull (a) bool {
	return (q.tail + 1) % q.maxSize == q.head
}

// Define a method to determine whether the ring queue is empty
func (q *circelQueue) IsEmpty(a) bool {
	return q.tail == q.head
}

// Get the number of elements in the ring queue
func (q *circelQueue) Size(a) int {
	return (q.tail + q.maxSize - q.head) % q.maxSize
}

// Define a method to display ring queue elements
func (q *circelQueue) List(a){
	// Check whether the queue is empty
	if q.Size() == 0 {
		fmt.Println("Queue empty")}// Define an auxiliary variable to point to head, temporary head
	tempHead := q.head
	for i := 0; i < q.Size(); i++ {
		fmt.Printf("arr[%d]=%d\t", tempHead, q.array[tempHead])
		tempHead = (tempHead + 1) % q.maxSize
	}
	fmt.Println()
}

func main(a){
	queue := &circelQueue{
		maxSize: 5,
		array:   [5]int{},
		head:    0,
		tail:    0,}var key string
	var val int
	// Add data
	for {
		fmt.Println("1. Add add data to queue")
		fmt.Println("2. Get gets data from the queue")
		fmt.Println("3.show display queue")
		fmt.Println("4. Exit the queue")

		fmt.Scanln(&key)
		switch key {
		case "add":
			fmt.Println("Enter the data you want to queue.")
			fmt.Scanln(&val)
			err := queue.Push(val)
			iferr ! =nil {
				fmt.Println(err)
			} else {
				fmt.Println("Made the team.")}case "get":
			val, err := queue.Pop()
			iferr ! =nil {
				fmt.Println(err)
			} else {
				fmt.Println("The number of queue exits is:", val)
			}
		case "show":
			queue.List()
		case "exit":
			os.Exit(0)}}}/ / summary:
// Ring queue can solve the problem that one-way queue does not effectively utilize the effective space of array
// The implementation of the ring queue also fits most application scenarios
Copy the code