Go 队列学习与实现

13 篇文章 7 订阅

先进先出

是一个有序列表,可以用数组或者是链表来实现

应用场景:排队.

用数组模拟队列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P5hD7Ucl-1677919264527)(../../images/Pasted%20image%2020230301221950.png)]

maxSize 是队列的最大容量
front:队列前端
rear:队列后端

一个单向队列

package main  
  
import (  
   "errors"  
   "fmt"   "os")  
  
// 结构体管理队列  
type Queue struct {  
   MaxSize int  
   array   [4]int //数组  
   front   int    //指向队列首部  
   rear    int    //指向队列的尾部  
}  
  
func (this *Queue) addqueue(value int) (err error) {  
   // 判断队列是否满了  
   if this.rear == this.MaxSize-1 {  
      return errors.New("queue full")  
   }  
   this.rear++  
   this.array[this.rear] = value  
   return  
  
}  
  
// 显示队列  
func (this *Queue) ShowQueue() {  
  
   //front不包含队首元素  
   for i := this.front + 1; i <= this.rear; i++ {  
      fmt.Printf("array[%d]=%d\t\n", i, this.array[i])  
   }  
   println()  
}  
  
// 队列中取出数据  
func (this *Queue) GetQueue() (val int, err error) {  
   if this.rear == this.front {  
      return -1, errors.New("queue empty")  
  
   }  
   this.front++  
   val = this.array[this.front]  
   return val, err  
  
}  
  
func main() {  
   // 创建一个队列  
   queue := &Queue{  
      MaxSize: 5,  
      front:   -1,  
      rear:    -1,  
   }  
   // 添加:  
   var key string  
   var val int  
   for true {  
      fmt.Println("1.输入add表示添加数据")  
      fmt.Println("2.输入get表示从队列中获取数据")  
      fmt.Println("3.输入show表示显示队列")  
      fmt.Println("3.输入exit表示退出")  
      fmt.Scanln(&key)  
      switch key {  
      case "add":  
         fmt.Println("输入你要入队列列数")  
         fmt.Scanln(&val)  
         err := queue.addqueue(val)  
         if err == nil {  
            fmt.Println("加入队列成功了")  
  
         } else {  
            fmt.Println(err.Error())  
         }  
      case "get":  
         val, err := queue.GetQueue()  
         if err != nil {  
            println(err.Error())  
         } else {  
            println("从队列中取出的一个数是:", val)  
         }  
      case "show":  
         queue.ShowQueue()  
      case "exit":  
         os.Exit(0)  
      default:  
         println("输入错误")  
         os.Exit(0)  
      }  
   }  
}

环形队列

其实就是在单向队列取模之后就环形了

利用数组来做环形.(是通过取模的方法)

注意点:

  • 尾索引的下一个为头索引时,表示队列就满了. 所以意思就是要保持队列空一个
  • tail == head 为空
  • (tail + 1) % maxSize =head 队列就满了
    初识化时, tail和head 都是0
    计算当前队列中共有多少元素:(tail + maxSize -head )% maxSize
package main  
  
import (  
   "errors"  
   "fmt"   "os")  
  
//环形队列  
  
// 结构体管理环形队列  
type CicleQueue struct {  
   maxSize int  
   array   [4]int  
   head    int  
   tail    int  
}  
  
func (this *CicleQueue) addqueue(val int) (err error) {  
   if this.IsFull() {  
      return errors.New("对列满了 ")  
   }  
   this.array[this.tail] = val  
   this.tail = (this.tail + 1) % this.maxSize  
   return  
}  
  
func (this *CicleQueue) GetQueue() (value int, err error) {  
   if this.isEpmpty() {  
      return 0, errors.New("queue Empty")  
  
   }  
   value = this.array[this.head]  
   this.head = (this.head + 1) % this.maxSize  
   return  
}  
  
// 判断环形队列是不是满了  
  
func (this *CicleQueue) IsFull() bool {  
   return (this.tail+1)%this.maxSize == this.head  
}  
  
// 判断是不是空  
func (this *CicleQueue) isEpmpty() bool {  
   return this.tail == this.head  
  
}  
  
// 判断多少元素  
func (this *CicleQueue) Size() int {  
   return (this.tail + this.maxSize - this.head) % this.maxSize  
}  
  
func (this *CicleQueue) ShowQueue() {  
   if this.isEpmpty() {  
      println("对列是空的")  
   }  
   len := this.Size()  
   temp := this.head  
   for i := 0; i < len; i++ {  
      fmt.Printf("arr[%d]=%d\t\n", temp, this.array[temp])  
      temp = (temp + 1) % this.maxSize  
   }  
  
}  
  
func main() {  
   var queue = CicleQueue{  
      maxSize: 4,  
      head:    0,  
      tail:    0,  
   }  
   var key string  
   var val int  
   for true {  
      fmt.Println("1.输入add表示添加数据")  
      fmt.Println("2.输入get表示从队列中获取数据")  
      fmt.Println("3.输入show表示显示队列")  
      fmt.Println("3.输入exit表示退出")  
      fmt.Scanln(&key)  
      switch key {  
      case "add":  
         fmt.Println("输入你要入队列列数")  
         fmt.Scanln(&val)  
         err := queue.addqueue(val)  
         if err == nil {  
            fmt.Println("加入队列成功了")  
  
         } else {  
            fmt.Println(err.Error())  
         }  
      case "get":  
         val, err := queue.GetQueue()  
         if err != nil {  
            println(err.Error())  
         } else {  
            println("从队列中取出的一个数是:", val)  
         }  
      case "show":  
         queue.ShowQueue()  
      case "exit":  
         os.Exit(0)  
      default:  
         println("输入错误")  
         os.Exit(0)  
      }  
   }  
  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值