Python Queue 队列 数据结构

发布于 2022-02-03 13:13:26 字数 3490 浏览 1346 评论 0

单链队列实现

使用 Python 中的列表 List 实现:

enqueue(item) —— 将一个元素入队(在队尾添加元素)

def enqueue(self, item):
  self.data.append(item)

dequeue() —— 将队首的元素出队,若队列为空则报错

def dequeue(self):
  if self.data:
    return self.data.pop(0)
  else:
    raise DequeueError("Queue is empty.")

size() —— 返回队列长度

is_empty() —— 判断队列是否为空

介绍

队列满足先进先出 FIFO 的原则。时间复杂度:出队列使用了列表的 pop(0) 方法,故时间复杂度为 O(n);入队列采用了列表的 append() 方法,故时间复杂度为 O(1)

采用循环队列(Circular Queue),可以将出队和入队的时间复杂度都降到 O(1)。循环队列有一个最大长度max_size,仍然采用列表实现。两个成员变量frontrear分别为队首元素和下一个入队的元素在列表中的索引。为了区别队列为空和队列为满,列表大小应为length = max_size + 1,列表中最多只能有max_size个队列元素。

当进行入队操作时,先判断队列是否已满(rear + 1) % length == front,一种方法是已满直接报错,另一种是若队列已满则扩容为原来的两倍。入队时,rear = (rear + 1) % max_size

进行出队操作时,先判断队列是否为空front == rear,如果为空则报错。出队时,front = (front + 1) % max_size

获得当前队列长度(rear - front + length) % length

使用循环队列的方法,由于入队和出队操作都是直接通过索引访问列表,所以时间复杂度都是 O(1)

循环队列

class CircularQueue:
  def __init__(self, max_size = 6):
    self.data = [None]*(max_size+1)
    self.front = 0
    self.rear = 0

get_max_size() —— 获得队列的最大长度

def get_max_size(self):
  return len(self.data) - 1

enqueue_strict(item) —— 入队操作,如果队列已满则报错

def enqueue_strict(self, item):
  if (self.rear+1) % len(self.data) == self.front:
    raise SizeError("Queue is full. Unable to enqueue.")
  self.data[self.rear] = item
  self.rear = (self.rear+1) % len(self.data)

dequeue_strict() —— 出队操作,如果队列为空则报错

def dequeue_strict(self):
  if self.front == self.rear:
    raise SizeError("Queue is empty. Unable to dequeue.")
  item = self.data[self.front]
  self.data[self.front] = None
  self.front = (self.front + 1) % len(self.data)

enqueue(item) —— 入队操作,如果已满则扩容为原来队列大小的两倍再入队

def enqueue(self, item):
  if (self.rear+1) % len(self.data) == self.front:
    self.resize(self.get_max_size() * 2)
  self.data[self.rear] = item
  self.rear = (self.rear+1) % len(self.data)

dequeue() —— 出队操作,检测如果队列大小等于列表大小的1/4,并且列表大小大于等于2,则减小列表大小为原来的一半以节省空间开销

def dequeue(self):
  if self.front == self.rear:
    raise SizeError("Queue is empty. Unable to dequeue.")
  item = self.data[self.front]
  self.data[self.front] = None
  self.front = (self.front + 1) % len(self.data)
  if self.size() == self.get_max_size()//4 and len(self.data) >= 2:
    self.resize(self.get_max_size() // 2)
  return item

size() —— 返回队列的当前大小

def size(self):
  return (self.rear - self.front + len(self.data)) % len(self.data)

is_empty() —— 判断队列是否为空

def is_empty(self):
  return self.front == self.rear

双端队列(Deque)

双端队列(Deque)与队列的区别就是,元素可以从两端插入,也可以从两端删除;具备队列与栈的特征,但其中的元素不具备FIFO或者LIFO的顺序,插入和删除操作的规律性需要用户自己维持。

双端队列的一些操作实现,使用Python的列表实现,队首(front)为列表的末尾,队尾(rear)为列表的首部:

class Deque:
  def __init__(self):
    self.data = []
  • is_empty()
  • size() -- 返回队列的大小
  • add_front(item) -- 在队首添加元素: self.data.append(item)
  • add_rear(item) -- 在队尾添加元素: self.data.insert(0, item)
  • remove_front() -- 从队首删除元素: return self.data.pop()
  • remove_rear() -- 从队尾删除元素: return self.data.pop(0)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文