Queue
队列的特点就是FIFO(first in first out),即先进先出,其添加数据项时仅添加到队列的末尾,删除数据时也仅从队列首端删除,其在日常有许多应用,比如排队、键盘打字缓冲以及打印机等等。队列在算法中的应用最为基础的就是hotPotato算法。以下便是我在队列学习中的总结。
首先来定义Queue类:
class Queue :
def __init__(self) :
self.items = [] #用list来装载queue的数据
def is_empty(self) :
return self.items == []
def size(self) :
return len(self.items)
def enqueue(self,new_item) :
self.items.insert(0,new_item) #list首端作为queue尾端,其尾端为queue首端(相当于把列表按照原顺序直接倒过来)
def dequeue(self) :
return self.items.pop()
之前学习中较为困惑的地方就是enqueue的实现,我们通过列表来体现队列,而队列的尾端刚好对应的就是列表的首端,二者反向是相反的,从队列末尾添加数据项就相当于添加在列表首端,这是队列较为特殊的地方。
接下来便是热土豆算法,hotPotato算法的过程就是队列首端的人拿到热土豆并传给后面的人,同时自己从首端转移到队列尾端,大家依次这样做,等满足需要传递的次数后,当前排在队列首端的人会被淘汰,就这样不断循环,最终剩下的一个人为幸存者。
def hot_potato(name_list,num) : #num为传递次数
name_queue = Queue()
for i in name_list :
name_queue.enqueue(i) #name_queue : rear['josef','kyrie','jordan','mike','bill']front
while name_queue.size() > 1 : #队列中只留一个人
for i in range(num) :
name_queue.enqueue(name_queue.dequeue()) #移除队首数据项的同时将其加入队尾
name_queue.dequeue() #淘汰队首数据项
return name_queue.dequeue() #返回最终幸存者
print(hot_potato(['bill','mike','jordan','kyrie','josef'],5))
其运行结果为kyrie。
Deque
双端队列可以通过首端和尾端添加或删除数据项,可以当Stack和queue的结合,但是还得通过操作者来实现栈和队列的特性。其应用的基础算法问题则是回文检测算法,用于判断一段字符串中的字符是否对称排列。先来定义双端队列:
class Deque :
def __init__(self) :
self.items = [] #用列表来承载队列的数据项
def is_empty(self) :
return self.items == []
def size(self) :
return len(self.items)
def add_front(self,new_item) : #队列首端(相当于列表尾端)添加数据项
self.items.append(new_item) #列表尾端用append函数
def add_rear(self,new_item) : #队列尾端(相当于列表首端)添加数据项
self.items.insert(0,new_item) #列表首端用insert函数
def remove_front(self) :
return self.items.pop() #记得返回其移除的数据项
def remove_rear(self) :
return self.items.pop(0) #同上,返回移除数据项
这里对于我而言难点是对那四个添加删除功能的理解,要理解列表和双端队列间的关系,其和队列间的关系一样,相当于把列表倒过来,数据项排列顺序不变。
接着就是Deque的应用-----回文检测算法,其核心思想就是利用双端队列两头出进的特性将字符串字符弹出,如果该字符串是回文字符串则每次两端弹出的两个字符应该是相等的,这样就可以判断一个字符串是否为回文字符串了。算法代码如下:
def qal_checker(String) :
char_deque = Deque()
still_equal = True
for i in String : #将字符串中的字符添加到双端队列中
char_deque.add_rear(i)
while char_deque.size() > 1 and still_equal :
first = char_deque.remove_front()
last = char_deque.remove_rear()
if first != last : #弹出首尾数据项并判断是否相等
still_equal = False
return still_equal
print(qal_checker("agbzbhub"))
print(qal_checker("abaccaba"))
运行结果分别为False和True。
参考资料:Problem Solving with Algorithms and Data Structures using Python