1. 栈
- 类似于一个口的客栈,先进去的后出来,后进去的先出来,代码实现如下:
- Stack() 创建一个空的新栈。 它不需要参数,并返回一个空栈。
- push(item)将一个新项添加到栈的顶部。它需要 item 做参数并不返回任何内容。
- pop() 从栈中删除顶部项。它不需要参数并返回 item 。栈被修改。
- isEmpty() 测试栈是否为空。不需要参数,并返回布尔值。
- size() 返回栈中的 item 数量。不需要参数,并返回一个整数。
class Stack():
def __init__(self): # 实例化一个空栈
self.items = [] # 容器
def push(self,item): # item就是向栈中添加的元素(从栈顶添加到栈底)
self.items.append(item)
def pop(self):
return self.items.pop()
def isEmpty(self):
return self.items == []
def size(self):
return len(self.items)
# 实例化一个空栈
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.pop()) # 3
print(stack.pop()) # 2
print(stack.pop()) # 1
- 应用:每个 web 浏览器都有一个返回按钮。当你浏览网页时,这些网页被放置在一个栈中(实际是网页的网址)。你现在查看的网页在顶部,你第一个查看的网页在底部。如果按‘返回’按钮,将按相反的顺序浏览刚才的页面
2. 队列
- 类似于两个口的胡同,一个只进,一个只出,且先进的先出,代码如下:
- Queue() 创建一个空的新队列。 它不需要参数,并返回一个空队列。
- enqueue(item) 将新项添加到队尾。 它需要 item 作为参数,并不返回任何内容。
- dequeue() 从队首移除项。它不需要参数并返回 item。 队列被修改。
- isEmpty() 查看队列是否为空。它不需要参数,并返回布尔值。
- size() 返回队列中的项数。它不需要参数,并返回一个整数。
# 队列实现思路:先进先出,将元素存于列表中,添加时永远插在索引为0的位置,取出时永远取索引的最后一个
class Queue():
def __init__(self): # 实例化一个空队列
self.items = []
def enqueue(self,item): # 添加元素
self.items.insert(0,item)
def dequeue(self): # 取元素
return self.items.pop()
def isEmpty(self): # 是否为空
return self.items == []
def size(self): # 判断长度
return len(self.items)
q = Queue()
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
print(q.dequeue())
print(q.dequeue())
print(q.dequeue())
- 应用场景:
- 我们的计算机实验室有 30 台计算机与一台打印机联网。当学生想要打印时,他们的打印任务与正在等待的所有其他打印任务“一致”。第一个进入的任务是先完成。如果你是最后一个,你必须等待你前面的所有其他任务打印
- 案例:烫手的山芋
- 烫手山芋游戏介绍:6个孩子围城一个圈,排列顺序孩子们自己指定。第一个孩子手里有一个烫手的山芋,需要在计时器计时1秒后将山芋传递给下一个孩子,依次类推。规则是,在计时器每计时7秒时,手里有山芋的孩子退出游戏。该游戏直到剩下一个孩子时结束,最后剩下的孩子获胜。请使用队列实现该游戏策略,排在第几个位置最终会获胜。
- 关键因素:
- 必须要保证手里有山芋的孩子永远在队头的位置
- 结论:
- 计时器计时7秒或者山芋被传递6次则一轮游戏结束,淘汰一个孩子,游戏继续。
# 队列实现思路:先进先出,将元素存于列表中,添加时永远插在索引为0的位置,取出时永远取索引的最后一个
class Queue():
def __init__(self): # 实例化一个空队列
self.items = []
def enqueue(self,item): # 添加元素
self.items.insert(0,item)
def dequeue(self): # 取元素
return self.items.pop()
def isEmpty(self): # 是否为空
return self.items == []
def size(self): # 判断长度
return len(self.items)
kids = ['A','B','C','D','E','F']
# 将孩子加入到队列中
kids_queue = Queue() # 实例化一个空队列
for kid in kids:
kids_queue.enqueue(kid)
while kids_queue.size() > 1: # 长度为1时结束
for i in range(6):
first_kid = kids_queue.dequeue()
kids_queue.enqueue(first_kid)
# 6次传递结束之后需要将队头孩子删除出队列
kids_queue.dequeue()
print('获胜的孩子是:',kids_queue.dequeue())
3. 二分查找
- 有序列表对于我们的实现搜索是很有用的。在顺序查找中,当我们与第一个元素进行比较时,如果第一个元素不是我们要查找的,则最多还有 n-1 个元素需要进行比较。 二分查找则是从中间元素开始,而不是按顺序查找列表。 如果该元素是我们正在寻找的元素,我们就完成了查找。 如果它不是,我们可以使用列表的有序性质来消除剩余元素的一半。如果我们正在查找的元素大于中间元素,就可以消除中间元素以及比中间元素小的一半元素。如果该元素在列表中,肯定在大的那半部分。然后我们可以用大的半部分重复该过程,继续从中间元素开始,将其与我们正在寻找的内容进行比较。
- 例题:给定列表,用二分查找,查找元素7
# 二分查找的前提是序列有序,所以先排序
# lst = [1,3,11,18,4,5,7,9]
# print(sorted(lst))
def find(alist, item):
# left,right表示列表的起始索引
left = 0
right = len(alist) - 1
isFind = False # 是否找到的标识
while left <= right:
# 中间值的索引,地板除
mid_index = (right + left) // 2
# 中间值大于要查找的值,right移动
if alist[mid_index] > item:
right = mid_index - 1
else:
# 查找到,修改isFind,并终止循环
if alist[mid_index] == item:
isFind = True
break
else:
left = mid_index + 1
return isFind
alist = [1, 3, 4, 5, 7, 9]
print(find(alist, 7))