队列是一种先进先出(FIFO)的数据结构,因此对队列的操作涉及到队列的头部和尾部。若用python中的顺序表(list)实现,出队用pop(0),入队用append()实现,则删除list头部数据的开小较大,不是一种高效的实现。但可是使用list作为储存队列的空间,实现队列需要一个头部元素位置的引用,以及当前队列的长度。具体实现原理如下:
由上图可以总结出实现的思路:
- 用一个固定大小的列表存储队列元素,此外每次操作后需更新队头位置,以及队列长度。
- 入队时,每次在队尾位置后添加元素,若队尾位置到了最后且列表还有空间,则在0位置添加元素。
- 入队时,若队列长度达到了列表的容量则需开辟一块更大的空间,此时需要将队列全部元素取出,放到新的列表中,且队头位置为0。
#基于顺序表实现的队列
class SQueue():
def __init__(self,init_len=8):
self._len=init_len #容量
self._elems=[0]*init_len #存储元素的list
self._head=0 #队头位置
self._num=0 #队里元素个数
def is_empty(self): #判断队列是否为空
return self._num==0
def peek(self): #获取队头的元素
if self.is_empty():
print("当前队列为空")
return
return self._elems[self._head]
def dequeue(self): #出队
if self.is_empty():
print("当前队列为空")
return
e=self._elems[self._head]
self._num-=1
self._head=(self._head+1)%self._len
return e
def __extend(self): #扩充容量
old_len=self._len
self._len*=2
new_elems=[0]*self._len
for i in range(old_len):
new_elems[i]=self._elems[(self._head+i)%old_len]
self._elems=new_elems
self._head=0
def enqueue(self,e): #入队
if self._num==self._len:
self.__extend()
self._elems[(self._head+self._num)%self._len]=e
self._num+=1