Go-数组-实现队列

package main

import (
	"errors"
	"fmt"
)

// 队列
// 特征:
// 		1. 按照元素的添加顺序排序,并且容量固定
//		2. 添加元素,放入末尾
//		3. 移出元素,将最先加入的元素移出
//		4. First In First Out -> FIFO
// 实现(头指针 + 尾指针 + 保存元素的元组):
//		1. 数组
//		2. 链表
// 思路:
//		1. 头指针 + 尾指针 + 保存元素的元组
// 		2. 两个方法 Add() Get()
//		3. 判空 empty,判满 full

// Go 实现队列思路
// 	1. queue结构体, buf存储数据, head通过切片下标指向队列头部,tail通过切片下标指向队列尾部,但tail指向的下标不存放元素
//  2. 添加元素使用 Push方法,移动tail指针,如果 tail指针值超过最大值,则重置tail指针指向0, overFlow置为 true
// 	3. 读取元素使用 Pop方法,移动head指针,如果head指针等于最大值,则重置head指针为0, overflown置为false
//  4. 判空:如果 overflown为false且 head = tail时候为空
//  5. 判满: 如果 overflown为false且 tail = maxSize 时为满,如果overflown为true且 tail -1 = head 时候为满
//  难点: 什么时候head 和 tail指针归0,如何空与判满


// queue 模拟队列
type queue struct {
	// buf 存放元素
	buf []int
	// 一个指向队列的头部,一个指向尾部,但尾部指向的位置不包含元素
	head, tail int
	// 判断头部是否溢出
	overflow bool
	maxSize int
}

func NewQueue(size int)  *queue {
	return &queue{
		buf : make([]int, size + 1),
		maxSize: size,
	}
}

// Push 向队列中添加一个元素
func (q *queue) Push(elem int) (err error) {

	// 1. 判满
	if q.overflow {
		if q.tail - 1 == q.head {
			err = errors.New("Q 满")
			fmt.Println(err)
			return err
		}
	} else {
		if q.tail == q.maxSize {
			err = errors.New("Q 满")
			return err
		}
	}
	// 1. 添加元素,应该头指针指向的下标不存储元素
	q.tail ++
	q.buf[q.tail - 1] = elem
	// 如果 q.tail 结果为maxSize则值为0
	if q.tail == q.maxSize {
		q.tail = 0
		q.overflow = true
	}
	return
}

// Pop 从队列中移出一个元素
func (q *queue) Pop() (elem int, err error) {
	// 1. 判空
	if !q.overflow {
		if  q.tail == q.head {
			err = errors.New("Q 空")
			fmt.Println(err)
			return -1, err
		}
	}
	// 1. 移出元素,获取头指针指向的元素,并且将头指针加上1
	elem = q.buf[q.head]
	q.head ++
	// 2. 如果 q.head 值等于最大值则重置为0
	if q.head == q.maxSize {
		q.head = 0
		q.overflow = false
	}
	return
}

// Show 显示队列中的元素
func (q *queue) Show() {
	data := make([]int, 0 , q.maxSize)
	if q.overflow {
		data = append(data, q.buf[:q.tail]...)
		data = append(data, q.buf[q.head:q.maxSize]...)
	} else {
		data = append(data, q.buf[q.head:q.tail]...)
	}
	fmt.Println(data)
}

func main() {
	q := NewQueue(3)
	q.Push(3)
	q.Push(4)
	q.Push(5)

	
	q.Pop()
	q.Pop()
	q.Pop()
	q.Pop()
	q.Pop()
	q.Show()
	q.Pop()
	q.Show()
}

  

原文地址:https://www.cnblogs.com/2bjiujiu/p/14427672.html