1. 程式人生 > 其它 >go陣列實現環形佇列

go陣列實現環形佇列

package main

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

// CircleQueue 環形佇列
type CircleQueue struct {
	maxSize int
	arr     [5]int
	head    int // 隊首
	tail    int // 隊尾
}

func main() {
	queue := CircleQueue{
		maxSize: 5,
		arr:     [5]int{},
		head:    0,
		tail:    0,
	}

	var key string
	var val int
	for {
		fmt.Println("1  add 新增資料到佇列")
		fmt.Println("2  get 從佇列獲取資料")
		fmt.Println("3  show 顯示佇列")
		fmt.Println("4  exit 退出佇列")

		fmt.Scanln(&key)

		switch key {
		case "add":
			fmt.Println("請輸入一個數")
			fmt.Scanln(&val)
			err := queue.Push(val)
			if err != nil {
				fmt.Println("新增錯誤", err)
			} else {
				fmt.Println("新增成功")
			}
		case "get":
			val, err := queue.Pop()
			if err != nil {
				fmt.Println(err.Error())
			}
			fmt.Printf("取出一個數 %d\n", val)

		case "show":
			queue.Show()

		case "exit":
			os.Exit(0)
		}

	}

}
func (q *CircleQueue) Push(val int) error {
	if q.IsFull() {
		return errors.New("佇列已滿")
	}

	// tail 在佇列尾部 但是不包含最後的元素
	q.arr[q.tail] = val
	q.tail = (q.tail + 1) % q.maxSize

	return nil
}

func (q *CircleQueue) Pop() (int, error) {
	if q.IsEmpty() {
		return 0, errors.New("佇列為空")
	}
	// head指向隊首 並且包含隊首元素
	val := q.arr[q.head]
	q.head = (q.head + 1) % q.maxSize
	return val, nil
}

// IsEmpty  佇列是否為空
func (q *CircleQueue) IsEmpty() bool {
	return q.tail == q.head
}

func (q *CircleQueue) IsFull() bool {
	return (q.tail+1)%q.maxSize == q.head
}

func (q *CircleQueue) Size() int {
	return (q.tail + q.maxSize - q.head) % q.maxSize
}

func (q *CircleQueue) Show() {
	fmt.Println("環形佇列情況如下 ",q.head,q.tail)
	size := q.Size()
	if size == 0 {
		fmt.Println("佇列為空")
	}
	tempHead := q.head
	for i := 0; i < size; i++ {
		fmt.Printf("arr[%d]=%d\n", tempHead, q.arr[tempHead])
		tempHead = (tempHead + 1) % q.maxSize
	}
}