循环队列使用一段固定的空间,当尾指针指向队列尾时,如果有新元素添加进来而队列非空,可以将尾指针重新指向最开始的存储空间。循环队列的核心是队列空和满的判定,我们少用一个元素来区分队列空和队列满,约定 front 指向队列头元素,rear 指向队列尾元素的下一个位置,队列内容为 $[front,rear)$。
// 循环队列结构定义
typeMyCircularQueuestruct{queue[]intfront,rearint// front指向第一个元素,rear指向最后一个元素的下一个位置
}/** Initialize your data structure here. Set the size of the queue to be k. */funcConstructor(kint)MyCircularQueue{returnMyCircularQueue{make([]int,k+1),0,0}}/** Insert an element into the circular queue. Return true if the operation is successful. */func(this*MyCircularQueue)EnQueue(valueint)bool{ifthis.IsFull(){returnfalse}this.queue[this.rear]=valuethis.rear=(this.rear+1)%len(this.queue)//尾指针防止溢出
returntrue}/** Delete an element from the circular queue. Return true if the operation is successful. */func(this*MyCircularQueue)DeQueue()bool{ifthis.IsEmpty(){returnfalse}this.front=(this.front+1)%len(this.queue)//头指针防止溢出
returntrue}/** Get the front item from the queue. */func(this*MyCircularQueue)Front()int{ifthis.IsEmpty(){return-1}returnthis.queue[this.front]}/** Get the last item from the queue. */func(this*MyCircularQueue)Rear()int{ifthis.IsEmpty(){return-1}returnthis.queue[(this.rear-1+len(this.queue))%len(this.queue)]//尾指针返回正确的位置
}/** Checks whether the circular queue is empty or not. */func(this*MyCircularQueue)IsEmpty()bool{ifthis.front==this.rear{returntrue}returnfalse}/** Checks whether the circular queue is full or not. */func(this*MyCircularQueue)IsFull()bool{if(this.rear+1)%len(this.queue)==this.front{returntrue}returnfalse}
typeMyQueuestruct{in[]intout[]int}/** Initialize your data structure here. */funcConstructor()MyQueue{returnMyQueue{}}/** Push element x to the back of queue. */func(this*MyQueue)Push(xint){this.in=append(this.in,x)}/** Removes the element from in front of queue and returns that element. */func(this*MyQueue)Pop()int{iflen(this.out)==0{fori:=len(this.in)-1;i>=0;i--{this.out=append(this.out,this.in[i])}this.in=nil}pop:=this.out[len(this.out)-1]this.out=this.out[0:len(this.out)-1]returnpop}/** Get the front element. */func(this*MyQueue)Peek()int{iflen(this.out)==0{fori:=len(this.in)-1;i>=0;i--{this.out=append(this.out,this.in[i])}this.in=nil}returnthis.out[len(this.out)-1]}/** Returns whether the queue is empty. */func(this*MyQueue)Empty()bool{iflen(this.in)==0&&len(this.out)==0{returntrue}else{returnfalse}}
typeMyStackstruct{q[]intt[]int}/** Initialize your data structure here. */funcConstructor()MyStack{returnMyStack{}}/** Push element x onto stack. */func(this*MyStack)Push(xint){this.q=append(this.q,x)}/** Removes the element on top of the stack and returns that element. */func(this*MyStack)Pop()int{ifthis.Empty(){return-1}forlen(this.q)>1{this.t=append(this.t,this.q[0])this.q=this.q[1:]}pop:=this.q[0]this.q=nilifthis.t!=nil{fori:=0;i<len(this.t);i++{this.q=append(this.q,this.t[i])}}this.t=nilreturnpop}/** Get the top element. */func(this*MyStack)Top()int{ifthis.Empty(){return-1}forlen(this.q)>1{this.t=append(this.t,this.q[0])this.q=this.q[1:]}pop:=this.q[0]this.q=nilthis.t=append(this.t,pop)ifthis.t!=nil{fori:=0;i<len(this.t);i++{this.q=append(this.q,this.t[i])}}this.t=nilreturnpop}/** Returns whether the stack is empty. */func(this*MyStack)Empty()bool{iflen(this.q)==0{returntrue}else{returnfalse}}