github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/queue/circular_queue.go (about) 1 package queue 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 ) 8 9 // 环形数组队列 10 type CircularQueue struct { 11 data []interface{} 12 head, tail, capacity int 13 } 14 15 func NewCircularQueue(cap int) *CircularQueue { 16 rcap := cap + 1 17 return &CircularQueue{ 18 data: make([]interface{}, rcap, rcap), 19 head: 0, 20 tail: 0, 21 capacity: rcap, 22 } 23 } 24 25 func (q *CircularQueue) Dequeue() interface{} { 26 if q.IsEmpty() { 27 return nil 28 } 29 ret := q.data[q.head] 30 q.data[q.head] = nil 31 q.head = (q.head + 1) % q.capacity 32 return ret 33 } 34 35 func (q *CircularQueue) Enqueue(v interface{}) bool { 36 if (q.tail+1)%q.capacity == q.head { //满了 37 return false 38 } 39 q.data[q.tail] = v 40 q.tail = (q.tail + 1) % q.capacity 41 return true 42 } 43 44 func (q *CircularQueue) IsEmpty() bool { 45 return q.head == q.tail 46 } 47 48 func (q *CircularQueue) Len() int { 49 // 注意此时getSize的逻辑: 50 // 如果tail >= head,非常简单,队列中的元素个数就是tail - head 51 // 如果tail < head,说明我们的循环队列"循环"起来了,此时,队列中的元素个数为: 52 // tail + capacity - head;tail + capacity 表示绕过了环 53 if q.tail >= q.head { 54 return q.tail - q.head 55 } else { 56 return q.tail + q.capacity - q.head 57 } 58 } 59 60 func (q *CircularQueue) String() string { 61 var sb strings.Builder 62 sb.WriteString("head ") 63 for i := q.head; i%q.capacity != q.tail; i++ { 64 sb.WriteString(fmt.Sprintf("%v", q.data[i%q.capacity])) 65 if (i+1)%q.capacity != q.tail { // 非倒数第一个 66 sb.WriteString(",") 67 } 68 } 69 sb.WriteString(" tail size:" + strconv.Itoa(q.Len())) 70 sb.WriteString(", cap:" + strconv.Itoa(q.capacity)) 71 return sb.String() 72 } 73 74 // 动态扩容和缩容 75 func (q *CircularQueue) Poll() interface{} { 76 if q.IsEmpty() { 77 return nil 78 } 79 ret := q.data[q.head] 80 q.data[q.head] = nil 81 q.head = (q.head + 1) % q.capacity 82 83 len := q.Len() 84 // 长度等于容量的 1/4 进行缩容 容量的 1/2 85 if len == q.capacity/4 && q.capacity/2 != 0 { 86 q.resize(q.capacity / 2) 87 } 88 return ret 89 } 90 91 func (q *CircularQueue) Offer(v interface{}) bool { 92 if (q.tail+1)%q.capacity == q.head { // 满了 93 q.resize(2 * q.capacity) // 进行2倍的扩容 94 } 95 q.data[q.tail] = v 96 q.tail = (q.tail + 1) % q.capacity 97 return true 98 } 99 100 // 动态调整 101 func (q *CircularQueue) resize(cap int) { 102 rcap := cap + 1 103 nData := make([]interface{}, rcap, rcap) 104 len := q.Len() 105 for i := 0; i < len; i++ { 106 nData[i] = q.data[(q.head+i)%q.capacity] 107 } 108 // 重新赋值 109 q.head = 0 110 q.tail = len 111 q.data = nData 112 q.capacity = rcap 113 }