go语言数据结构第二篇-队列

队列介绍

  • 队列是一个有序列表,可以用数组或是链表来实现
  • 遵循先入先出的原则,即:先存入队列的数据,要先取出。后存入的要后取出
  • 数组模拟单向队列

 maxsize是该队列的最大容量, front随着数据的输出而改变,rear随着数据的输入而改变,

这里front=-1,rear=2,当存入数据时,rear=maxsize-1,队列刚好满

思路:

单向数组队列: 

package main

import (
	"fmt"
	"github.com/pkg/errors"
	"os"
)

type Queue struct {
	maxSize int	//队列容量
	array [5]int//数组->模拟队列
	front int	//表示指向队列的首部
	rear int	//表示指向队列的尾部
}

//添加数据到队列
func (this *Queue) AddQueue(val int) (err error) {
	//先判断队列是否已经满了
	if this.rear == this.maxSize-1{//队列刚好满了
		return errors.New("队列满了")
	}

	this.rear++ //尾指针后移
	this.array[this.rear] =val //将传来的值放入队列
	return
}


//从队列中取出数据
func (this *Queue) GetQueue() (val int, err error) {
	//先判断队列是否为空
	if this.rear == this.front { //队空
		return -1, errors.New("队列为空")
	}
	this.front++
	val = this.array[this.front]
	return val ,err
}

//显示队列,找到队首,然后遍历到队尾
func (this *Queue) ShowQueue()  {
	//this.front初始值为-1
	for i := this.front + 1;i <= this.rear;i++{
		fmt.Printf("array[%d]=%d\t",i,this.array[i])
	}
	fmt.Println()
}

//主函数
func main() {

	//先创建一个队列
	queue := &Queue{
		maxSize : 5,
		front : -1,
		rear : -1,

	}

	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.AddQueue(val)
			if err != nil {
				fmt.Println(err.Error())
			} else {

				fmt.Println("加入队列ok")
			}
		case "get":
			val, err := queue.GetQueue()
			if err != nil {
				fmt.Println(err.Error())
			} else {
				fmt.Println("从队列中取出了一个数=", val)
			}
		case "show":
			queue.ShowQueue()
		case "exit":
			os.Exit(0)
		}
	}
}
  • 数组模拟环形队列

 上面的代码实现了基本的队列结构,但是没有有效的利用数组空间,可以使用数组实现一个环形队列解决,如何实现呢?

可以通过取模的方式实现

注意:尾指针的下一个为头指针时表示队列满,即将队列空出一个容量作为约定,

(1)(rear + 1)% maxsize == front表示队列满

(2)   rear==front表示队列空

(3)   初始化时,front =0 ,rear = 0

(4)  怎么统计该队列一共多少元素?(rear + maxsize -head)%maxsize  

代码实现:

package main

import (
	"fmt"
	"github.com/pkg/errors"
	"os"
)

//使用一个结构体管理环形队列
type RoundQueue struct {
	maxSize int
	array [5]int
	front int 	//头指针
	rear int	//尾指针
}

//将数字入队列
func (this *RoundQueue) AddQueue(val int)(err error){
	if this.IsFull(){
		return errors.New("队列满,放入失败")
	}

	this.array[this.rear] = val
	this.rear = (this.rear + 1) % this.maxSize
	return

}

//从队列中拿出数字
func (this *RoundQueue) GetQueue()(val int,err error){
	if this.IsEmpty() {
		return 0,errors.New("队列空")
	}

	val = this.array[this.front]
	this.front = (this.front +1) % this.maxSize
	return 
}

//判断环形队列是否满,返回true为满
func (this *RoundQueue) IsFull() bool {
	return (this.rear + 1) % this.maxSize == this.front
}

//判断环形队列是否空,返回true为空
func (this *RoundQueue) IsEmpty() bool {
	return this.rear  == this.front
}

//返回队列中的元素总数
func (this *RoundQueue) Size() int {
	return (this.rear + this.maxSize -this.front) % this.maxSize
}

//显示队列
func (this *RoundQueue) ShowQueue()  {
	//取出当前队列有多少个元素
	size := this.Size()
	if size == 0{
		fmt.Println("队列为空")
	}

	//设计一个辅助变量,指向头指针
	temHead := this.front
	for i :=0;i < size ;i++{
		fmt.Printf("array[%d]=%d\t",temHead,this.array[temHead])
		temHead = (temHead + 1) % this.maxSize
	}

	fmt.Println()
}

//主函数
func main() {

	//初始化环形队列
	queue := &RoundQueue{
		maxSize : 5,
		front : 0,
		rear : 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.AddQueue(val)
			if err != nil {
				fmt.Println(err.Error())
			} else {

				fmt.Println("加入队列成功")
			}
		case "get":
			val, err := queue.GetQueue()
			if err != nil {
				fmt.Println(err.Error())
			} else {
				fmt.Println("从队列中取出了一个数=", val)
			}
		case "show":
			queue.ShowQueue()
		case "exit":
			os.Exit(0)
		}
	}
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值