队列和栈相反
- 队列: 先进先出(FIFO)
- 栈: 后进先出(LIFO)
类型
- 循环队列
- Disruptor高性能队列
- 并发队列(线程安全)
- 阻塞队列
顺序队列
使用python的list结构来模拟, 在右端插入的话时间复杂度是O(n)
, 在左端弹出的话是O(1)
方式一: 每次出队操作都要移动数组
# coding:utf-8
"""
使用列表模拟单端队列
左出右进
"""
class Queue(object):
"""
使用列表模拟实现单端队列
"""
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def size(self):
return len(self.items)
def enqueue(self, item):
self.items.append(item)
def dequeue(self):
"""
每次出队所有元素都会向前移动
:return:
"""
if self.isEmpty():
raise Exception("empty queue")
res = self.items.pop(0)
return res
方式二
每次出队时不用再移动所有元素, 只有当入队时如果tail指针在最尾部, 检测数组是否还有空间
- 如果还有空间, 移动所有元素后再添加
- 如果没有空间, 返回错误
# coding:utf-8
class Queue(object):
"""
队列
使用固定数组的形式, 优点是出队操作不用再每次都移动数组
只有当入队操作的时候, 如果数组内还有空余位置, 但是tail已经在最尾部了, 此时需要进行数据搬移
"""
def __init__(self, length):
self.items = [0 for _ in range(length)]
self.head = 0
self.tail = 0
self.length = length
def size(self):
return self.tail - self.head
def enqueue(self, item):
if self.tail >= self.length:
if self.head == 0:
raise Exception("Full")
# 进行数据搬移
for i in range(self.head, self.tail):
self.items[i - self.head] = self.items[i]
# 移动完毕后重新更新head和tail
self.tail = self.tail - self.head
self.head = 0
self.items[self.tail] = item
self.tail += 1
def dequeue(self):
if self.head >= self.tail:
raise Exception("Empty")
data = self.items[self.head]
self.head += 1
return data
if __name__ == "__main__":
q = Queue(10)
for i in range(10):
q.enqueue(i)
print(q.dequeue())
print(q.dequeue())
q.enqueue(11)
q.enqueue(12)
res = []
while True:
try:
res.append(q.dequeue())
except Exception as e:
print(e)
break
print(res)
"""
0
1
Empty
[2, 3, 4, 5, 6, 7, 8, 9, 11, 12]
"""
链式队列
# coding:utf-8
"""
基于链表实现的复杂度
"""
class Node(object):
def __init__(self, data, next_=None):
self.data = data
self.next_ = next_
class Queue(object):
def __init__(self):
self.head = None
self.tail = None
self.length = 0
def size(self):
return self.length
def enqueue(self, item):
if self.head == None:
self.head = Node(item)
self.tail = self.head
else:
self.tail.next_ = Node(item)
self.tail = self.tail.next_
self.length += 1
def dequeue(self):
if self.head == None:
raise Exception("Empty")
data = self.head.data
self.head = self.head.next_
self.length -= 1
return data
if __name__ == "__main__":
q = Queue()
for i in range(10):
q.enqueue(i)
res = []
while True:
try:
res.append(q.dequeue())
except Exception as e:
print(e)
break
print(res)
循环队列
该类型队列可以避免移动元素的操作
上图中队列大小是8. 判断队列满的条件是(tail + 1) % n = head
# coding:utf-8
"""
循环队列
"""
class QueueLoop(object):
def __init__(self, length):
self.items = [0 for _ in range(length)]
self.head = 0
self.tail = 0
self.length = length + 1 # 循环队列会多用一位, 因为当tail指向最后一个空位置时认为已经满了
def enqueue(self, item):
if self.is_full():
raise Exception("Full")
self.items[self.tail] = item
self.tail += 1
def dequeue(self):
if self.is_empty():
raise Exception("Empty")
data = self.items[self.head]
self.head = self.head + 1
return data
def is_empty(self):
if self.head == self.tail:
return True
else:
return False
def is_full(self):
"""
当tail指向head的前一位的时候认为队列已满
:return:
"""
if (self.tail + 1) % self.length == self.head:
return True
else:
return False
if __name__ == "__main__":
q = QueueLoop(10)
for i in range(10):
q.enqueue(i)
res = []
while True:
try:
res.append(q.dequeue())
except Exception as e:
print(e)
break
print(res)
"""
Empty
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
"""
"""
Empty
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
"""
资料
- <>-程杰
- 数据结构和算法之美-王争
原文地址:https://www.cnblogs.com/zlone/p/10989120.html
时间: 2024-10-10 03:19:29