golang实现循环队列的示例代码

  package QUEUE

  import (

  "strings"

  "sync"

  )

  type CycleQueue struct {

  data []interface{} //存储空间

  front int //前指针,前指针负责弹出数据移动

  rear int //尾指针,后指针负责添加数据移动

  cap int //设置切片最大容量

  mu sync.RWMutex // 添加互斥锁

  }

  func NewCycleQueue(cap int) *CycleQueue {

  return &CycleQueue{

  data: make([]interface{}, cap),

  cap: cap,

  front: 0,

  rear: 0,

  }

  }

  // 入队操作

  // 判断队列是否队满,队满则不允许添加数据

  func (q *CycleQueue) Push(data interface{}) bool {

  q.mu.Lock()

  defer q.mu.Unlock() // 确保在函数退出时释放锁

  //check queue is full

  if q.QueueLength() == q.cap { //队列已满时,不执行入队操作

  Log.Error("push err queue is full")

  return false

  }

  q.data[q.rear] = data //将元素放入队列尾部

  q.rear = (q.rear + 1) % q.cap //尾部元素指向下一个空间位置,取模运算保证了索引不越界(余数一定小于除数)

  return true

  }

  // 出队操作

  // 需要考虑: 队队为空没有数据返回了

  func (q *CycleQueue) Pop() interface{} {

  q.mu.Lock()

  defer q.mu.Unlock()

  if q.rear == q.front {

  return nil

  }

  data := q.data[q.front]

  q.data[q.front] = nil // 使用nil来避免内存泄露

  q.front = (q.front + 1) % q.cap

  return data

  }

  // 循环队列长度计算,考虑哨兵空间

  func (q *CycleQueue) QueueLength() int {

  if q.rear >= q.front {

  return q.rear - q.front

  }

  return q.cap - q.front + q.rear

  }

  func (q *CycleQueue) FindDataByRequestId(requestId string) interface{} {

  q.mu.Lock()

  defer q.mu.Unlock()

  // 计算队列中的有效元素数量

  length := q.QueueLength()

  // 从front指针开始遍历队列

  index := q.front

  for i := 0; i < length; i++ {

  // 检查当前元素是否包含requestId

  if data, ok := q.data[index].(string); ok && strings.Contains(data, requestId) {

  // 找到元素后,从队列中移除

  q.RemoveAtIndex(index)

  return data

  }

  // 移动到下一个元素

  index = (index + 1) % q.cap

  }

  // 如果没有找到,返回nil

  return nil

  }

  // 新增RemoveAtIndex方法,用于在循环队列中移除指定索引的元素

  func (q *CycleQueue) RemoveAtIndex(index int) {

  if index < 0 || index >= q.cap {

  return // 索引越界检查

  }

  // 将index位置的元素复制到最后一个元素的位置

  copy(q.data[index:], q.data[index+1:q.rear])

  // 更新队列的front和rear指针

  if index == q.rear { // 如果移除的是最后一个元素

  q.rear = index // rear指针向前移动

  } else if index < q.rear { // 如果移除的是中间的元素

  q.rear-- // rear指针向前移动

  }

  // 如果移除的是front指针前的元素

  if index < q.front {

  q.front = index // front指针向后移动

  }

  }