前言
Datawhale十月组队学习,LeetCode算法
一、队列基础知识
队列:一种线性数据结构,是一种只允许在表的一端进行插入操作,而在表的另一端进行删除操作的线性表。
我们把队列中允许插入的一端称为 队尾;把允许删除的另一端称为 队头。当表中没有任何数据元素时,称之为空队。
二、队列的顺序存储与链式存储
1.队列的顺序存储
代码如下:
class Queue:
# 初始化空队列
def __init__(self, size=100):
self.size = size
self.queue = [None for _ in range(size)]
self.front = -1
self.rear = -1
# 判断队列是否为空
def is_empty(self):
return self.front == self.rear
# 判断队列是否已满
def is_full(self):
return self.rear + 1 == self.size
# 入队操作
def enqueue(self, value):
if self.is_full():
raise Exception('Queue is full')
else:
self.rear += 1
self.queue[self.rear] = value
# 出队操作
def dequeue(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
self.front += 1
return self.queue[self.front]
# 获取队头元素
def front_value(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
return self.queue[self.front + 1]
# 获取队尾元素
def rear_value(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
return self.queue[self.rear]
我认为队列的顺序存储是在数组结构的基础上进行的操作,设计构造方法,在其中设置队列长度表示队列存储数据的最大值,队列的队头表示队列的数据出队的位置,队列的队尾表示数据入队的位置。但这种简单队列则会出现一个问题,在队尾指向队列的最后,而队头前面若有位置也无法在存入数据,会出现假满的情况,而循环队列的顺序存储则解决了这种情况。
2.循环队列的顺序存储
代码如下:
class Queue:
# 初始化空队列
def __init__(self, size=100):
self.size = size + 1
self.queue = [None for _ in range(size + 1)]
self.front = 0
self.rear = 0
# 判断队列是否为空
def is_empty(self):
return self.front == self.rear
# 判断队列是否已满
def is_full(self):
return (self.rear + 1) % self.size == self.front
# 入队操作
def enqueue(self, value):
if self.is_full():
raise Exception('Queue is full')
else:
self.rear = (self.rear + 1) % self.size
self.queue[self.rear] = value
# 出队操作
def dequeue(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
self.queue[self.front] = None
self.front = (self.front + 1) % self.size
return self.queue[self.front]
# 获取队头元素
def front_value(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
value = self.queue[(self.front + 1) % self.size]
return value
# 获取队尾元素
def rear_value(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
value = self.queue[self.rear]
return value
循环队列是在队列的基础上进行的操作,循环队列的存储结构并没有发生变化 ,只是再描述循环队列时看上去是一个循环头尾相连,这可以改变队列的缺陷,在假溢满的时候,可以再存储数据。在循环队列中因为队满和队空的条件一样,所以要改变数据存储的最大值,使其空出一个单位,用于区分队空和队满。
3.队列的链式存储
代码如下:
class Node:
def __init__(self, value):
self.value = value
self.next = None
class Queue:
# 初始化空队列
def __init__(self):
head = Node(0)
self.front = head
self.rear = head
# 判断队列是否为空
def is_empty(self):
return self.front == self.rear
# 入队操作
def enqueue(self, value):
node = Node(value)
self.rear.next = node
self.rear = node
# 出队操作
def dequeue(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
node = self.front.next
self.front.next = node.next
if self.rear == node:
self.rear = self.front
value = node.value
del node
return value
# 获取队头元素
def front_value(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
return self.front.next.value
# 获取队尾元素
def rear_value(self):
if self.is_empty():
raise Exception('Queue is empty')
else:
return self.rear.value
在队列的链式存储中,我认为应该是没有太难的难点。队列的链式存储中存在队头指针和队尾指针,其中的操作没有判断队满。
总结
我对队列的理解:队列是一种受限制的线性数据结构,与堆栈这一种线性数据结构类似,与线性数据结构相比,队列少了在数据中插入和删除数据,具有先进先出的特性。
在队列的顺序存储我认为是有点缺陷的在队尾指向队列的最后,而队头前面若有位置也无法在存入数据,会出现假满的情况。
在循环队列的顺序存储的难点是队空和队满的条件判断,很容易搞混,故要预留一个队列单位,成为队满的判断条件。
队列的链式存储在经过前面链表的学习,其实理解起来没有太大的困难,就是在单链表的基础上加一个一直指向最后一个的队尾指针,数据的输出在队头指针,输入在队尾指针。