python实现队列
队列(Queue):和栈一样,也是一种操作受限的线性表,但它只允许在表的一端进行插入,在另一端进行删除。分配一块连续的存储单元,并附带两个指针front和rear分别指示队首元素和队尾元素,一般队首指针指向队首元素,队尾指针指向队尾元素的下一个位置。定义了一个 Queue 类,表示链队列,其中包含 front 和 rear 两个指针,分别指向队列的头部和尾部。4)不可以用"rear=size"来判
队列(Queue):和栈一样,也是一种操作受限的线性表,但它只允许在表的一端进行插入,在另一端进行删除。操作特征是先进先出(FIFI,First In First Out)
队头(Front):允许删除的一端,又称为队首
队尾(Rear):允许删除的一端
空队列:不含有任何元素的空表
队列常见操作:
IniQueue():初始化队列,构造一个空队列
isempty():判空
isfull():判满
EnQueue():若队列未满,从队尾入队
DeQueue():若队列非空,从队首出队
GetHead():获取队首元素
顺序队列:
分配一块连续的存储单元,并附带两个指针front和rear分别指示队首元素和队尾元素,一般队首指针指向队首元素,队尾指针指向队尾元素的下一个位置。
class myQueue():
def __init__(self, size):#初始化一个空队列
self.size = size
self.front =0
self.rear = 0
self.queue = []
def enqueue(self, x): # 入队操作
if self.isfull():
print("queue is full")
return False
else:
self.queue.append(x)
self.rear = self.rear + 1
return True
def dequeue(self): # 出队操作
if self.isempty():
print("queue is empty")
return False
else:
duiwei = self.queue[self.front]
self.queue.pop(self.front)
return duiwei
def isfull(self):
return self.rear - self.front + 1 == self.size
def isempty(self):
return self.front == self.rear
def gethead(self):
if self.isempty():
return False
else:
return self.queue[self.front]
def show(self):
print(self.queue)
qq= myQueue(10)
print("初始化队列为空",qq.isempty())
for i in range(10):
qq.enqueue(i)
qq.show()
print("插入十个元素后,队满",qq.isfull())
print(qq.dequeue())
print(qq.dequeue())
print(qq.dequeue())
print(qq.dequeue())
输出为:
初始化队列为空 True
queue is full
[0, 1, 2, 3, 4, 5, 6, 7, 8]
插入十个元素后,队满 True
0
1
2
3
需要注意的地方:
1)初始状态(队列为空):front==rear=0
2)入队:队不满时,先送值到队尾元素,然后rear加1
3)出队:队非空时,先取队首元素的值,然后front加1
4)不可以用"rear=size"来判断队列是否为满,上图(d)也满足"rear=size",但不是队列为满,这是一种假溢出。
循环队列
顺序队列存在缺点,元素出队后该位置就空着而没有被利用,最终造成假溢出,新的元素也无法入队。使用循环队列来解决这个问题:即把存储队列元素的表从逻辑上看作一个环。
初始时:front=rear=0
出队时:front=(front+1)%size
入队时:rear=(rear+1)%size
元素个数:(rear+size-front)%size
队空的条件:rear=front
队满的条件:rear=front,如图所示,将会导致无法判断队空或者队满。
三种方式来区分队空还是队满:
1)牺牲一个单元,入队时少用一个队列单元,即队列的元素个数最大为size-1
元素个数:(rear+size-front)%size
队空的条件:rear=front
队满的条件:(rear+1)%size=front
2)队列增加一个元素个数的数据成员,elenum=0时队列为空,elenum=size时队列为满。
3)类型中增加一个tag数据成员,出队导致rear=front,tag=0,表示队空;入队导致rear=front,tag=1,表示队满
第一种方式的代码实现如下:
class myCycleQueue():
def __init__(self,size): #初始化
self.rear=0
self.front=0
self.size=size
self.queue=[]
def isempty(self): #判空
return True if self.front==self.rear else False
def isfull(self): #判满
return True if (self.rear+1)%self.size==self.front else False
def elenum(self): #获取元素个数
return (self.rear + self.size - self.front)%self.size
def enqueue(self,x): #入队
if self.isfull():
print("queue is full")
return False
else:
self.queue.append(x)
self.rear=(self.rear+1)%self.size
def dequeue(self): #出队
if self.isempty():
print("queue is empty")
return False
else:
x=self.queue[self.front]
self.front=(self.front+1)%self.size
self.queue.pop(self.front)
return x
链队列:
同时带有队头指针和队尾指针的单链表,头指针指向队头节点,队尾指针指向队尾结点。
class Node:
def __init__(self, value):
self.value = value
self.next = None
class Queue:
def __init__(self):
self.front = None # 队头指针
self.rear = None # 队尾指针
def is_empty(self):
return self.front is None
def enqueue(self, value):
new_node = Node(value)
if self.is_empty():
self.front = new_node
self.rear = new_node
else:
self.rear.next = new_node
self.rear = new_node
def dequeue(self):
if self.is_empty():
raise Exception("Queue is empty")
else:
value = self.front.value
self.front = self.front.next
if self.front is None:
self.rear = None
return value
def peek(self):
if self.is_empty():
raise Exception("Queue is empty")
else:
return self.front.value
# 创建一个示例队列
queue = Queue()
# 入队操作
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
# 出队操作
print(queue.dequeue()) # 输出: 1
print(queue.dequeue()) # 输出: 2
# 获取队头元素
print(queue.peek()) # 输出: 3
定义了一个 Node 类,表示链队列的节点,每个节点包含一个 value 值和一个 next 指针指向下一个节点。
定义了一个 Queue 类,表示链队列,其中包含 front 和 rear 两个指针,分别指向队列的头部和尾部。初始时,这两个指针都为空。
is_empty 方法用于判断队列是否为空,如果 front 为空,则队列为空。
enqueue 方法用于入队操作,创建一个新的节点,并根据队列是否为空来更新 front 和 rear 指针。
dequeue 方法用于出队操作,从队列的头部移除一个节点,并更新 front 指针。如果移除后队列为空,则同时更新 rear 指针。
peek 方法用于获取队头元素,即返回 front 指针指向的节点的值。
通过这种方式,实现了链队列的基本功能,包括入队、出队和获取队头元素等操作。链队列的入队和出队操作都能够在 O(1) 的时间复杂度内完成。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)