1. 队列的概念和性质
1.1 定义:
队列是一种有次序的数据集合,其特征是
- 新数据项的添加总发生在一端(通常称为“尾rear”端)
- 而现存数据项的移除总发生在另一端(通常称为“首front”端)
当数据项加入队列,首先出现在队尾,随着队首数据项的移除,它逐渐接近队首。
1.2 性质:
- FIFO First-in first-out 先进先出:新加入的数据项必须在数据集末尾等待,而等待时间最长的数据项则是队首
- 队列仅有一个入口和一个出口:不允许数据项直接插入队中,也不允许从中间移除数据项
1.3 例子:
- 排队:上银行办业务,先到的人排在前面,先接受服务。后面的人后接受服务。
2. 数据结构中的队列Queue
在数据结构中,我们用Queue这种抽象数据类型表示队列。
2.1 定义:
抽象数据类型Queue由如下操作定义:
- Queue():创建一个空队列对象,返回值为Queue对象;
- enqueue(item):将数据项item添加到队尾,无返回值;即入队。
- dequeue():从队首移除数据项,返回值为队首数据项,队列被修改;即出队
- isEmpty():测试是否空队列,返回值为布尔值
- size():返回队列中数据项的个数。
2.2 例子
例如
2.3 代码实现Queue
class Queue:
def __init__(self):
self.items = []
def enqueue(self, item): # 复杂度是 O(n)
self.items.insert(0, item) # 即,列表的最左端作为队尾,这是和栈最关键的区别
def dequeue(self): # 复杂度是 O(1)
return self.items.pop() # 即,列表的最右端作为队尾,这和栈是一样的
def isEmpty(self):
return self.items == []
def size(self):
return len(self.items)
# 测试
q = Queue()
q.enqueue("xxx")
print(q.items)
print(q.isEmpty())
print(q.size())
print(q.dequeue())
print(q.items)
print(q.isEmpty())
print(q.size())
3. 双端队列Deque
3.1 定义
双端队列是一种特殊的队列,这种队列数据项既可以从队首加入,也可以从
队尾加入;数据项也可以从两端移除。
某种意义上说,双端队列集成了栈和队列的能力
3.2 性质
双端队列并不具有内在的L IFO或者FIFO特性
如果用双端队列来模拟栈或队列,需要由使用者自行维护操作的一致性
4. 数据结构中的Deque
4.1 定义:
deque定义的操作如下:
- Deque():创建一个空双端队列
- addFront(item):将item加入队首
- addRear(item):将item加入队尾
- removeFront():从队首移除数据项,返回值为移除的数据项
- removeRear():从队尾移除数据项,返回值为移除的数据项
- isEmpty():返回deque是否为空
- size():返回deque中包含数据项的个数
4.2 例子
4.3 代码实现Deque
class Deque:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def addFront(self, item):
self.items.append(item)
def addRear(self, item):
self.items.insert(0, item)
def removeFront(self):
return self.items.pop()
def removeRear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
4.4 算法题:判断回文词:
4.4.1 问题:
“回文词”指正读和反读都一样的词,
如radar、madam、toot
中文“上海自来水来自海上”“山东落花生花落东山
4.4.2 解:
通过观察,每个词的字母构成都是左右对称的。我们使用双端队列存储每一个词的所有字母。字母从两端出队,当队列为空,或只剩下一个字母的时候,两端出队的字母相同,则是回文词。
class Deque:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def addFront(self, item):
self.items.append(item)
def addRear(self, item):
self.items.insert(0, item)
def removeFront(self):
return self.items.pop()
def removeRear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
def huiWenci(wordList):
dq = Deque()
for ch in wordList:
dq.addRear(ch)
stillEqual = True
while dq.size() > 1 and stillEqual:
first = dq.removeFront()
last = dq.removeRear()
if first != last:
stillEqual = False
return stillEqual
print(huiWenci("radar")) # True
print(huiWenci("toot")) # True
print(huiWenci("上海自来水来自海上")) # True
print(huiWenci("山东落花生花落东山")) # True
print(huiWenci("toor")) # False
print(huiWenci("山东落花生花落西山")) # False
参考文献
本文的知识来源于B站视频 【慕课+课堂实录】数据结构与算法Python版-北京大学-陈斌-字幕校对-【完结!】,是对陈斌老师课程的复习总结