Go 队列学习与实现

先进先出

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

应用场景:排队.

用数组模拟队列

Go 队列学习与实现_第1张图片

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)  
      }  
   }  
  
}

你可能感兴趣的:(GO,算法,golang,学习,数据结构)