前言
- 有Python基础
- 最好是学过数据结构的栈和队列
- 参考链接
队列:https://blog.csdn.net/sf9898/article/details/104941655
栈:https://blog.csdn.net/sf9898/article/details/104939489
原理
- 提出这样的一个问题,如何用队列去模拟栈,或者说,用队列实现栈的效果,即先进后出?
- 队列和栈的区别无非是先进先出和先进后出,那么在之前的博客中,二者的数据存储都是用的list类型,入队和入栈都是从list类型的items的尾部进去的,即采用append的方法。区别在于出的情况。队列是从头出,用的是pop(0),弹出items的第一个元素,栈是用的pop(),删除items最后一个元素。如果进行模拟,那么需要对这一点进行模拟。
实现
队列的类
class Queue(object):
def __init__(self):
self.items = []
def isEmpty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
def travel(self):
for i in self.items:
print(i, end=' ')
print('')
def push(self, item):
self.items.append(item)
# 这个是原来的pop函数,更名为pop1
def pop1(self):
self.items.pop(0)
# 需要改造下pop函数,使得这个函数有返回值
def pop(self):
return self.items.pop(0)
一个队列
- 假设用一个队列实现,那么可以将出队的元素加到队尾,之后一个一个进行此项操作,当发现是原来的最后一个元素时,将其删除,并打印它的值。因此需要有删除的函数和返回这个数值的函数。删除完原来的最后一个,那么开始删原来的倒数第二个…以此类推。完整代码如下。
class Queue(object):
def __init__(self):
self.items = []
def isEmpty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
def travel(self):
for i in self.items:
print(i, end=' ')
print('')
def push(self, item):
self.items.append(item)
# 这个是原来的pop函数,更名为pop1
def pop1(self):
self.items.pop(0)
# 需要改造下pop函数,使得这个函数有返回值
def pop(self):
return self.items.pop(0)
# 队列的基本功能的测试
q = Queue()
print(q.isEmpty()) # 应是True
for i in range(5):
q.push(i)
q.travel() # 0 1 2 3 4
for i in range(3):
q.pop1()
q.travel() # 3 4
print(q.size()) # 2
print('----------')
# 队列是先进先出,栈是先进后出
# 都是从尾加入,队列是从头出,栈是从尾出,因此需要针对出的这一块进行模拟
q1 = Queue()
# 进的方式是一样的,下面初始化一下
for i in range(20):
q1.push(i)
print('队列的出队顺序:', end=' ')
q1.travel()
# 假设只用一个栈,要使得输出的序列反过来(既要完成“出”的任务还要保证打印顺序)
# q1 出队的数加到末尾
N = q1.size()
print('栈的出栈顺序: ', end=' ')
# 下面的循环:第一次要把最后一个数移到开头需要进行N-1次,然后扔掉这个数,现在items的长度剩下N-1,
# 那么下一次将最后一个元素(即原来的倒数第二个元素)移到开头需要进行N-1-1即N-2次...
for j in range(1, N + 1):
for i in range(N - j):
q1.push(q1.pop())
print(q1.items[0], end=' ') # 打印一下当前的开头
q1.pop1() # 然后取出这个出头鸟
两个队列
- 假设用两个队列呢?假设q1不为空,q2是空的,那么可以将q1弹出元素直至只剩下最后一个元素,弹出的元素均加入到q2中,那么此时将q1中的元素弹出并打印。之后q1是一个空的队列,q2中装的是之前q1弹出的元素,即第一个元素到倒数第二个元素。此时将q1,q2交换,继续重复之前的操作,可以一个个弹出并打印出想要的结果,实现栈的先进后出的效果。代码如下。
class Queue(object):
def __init__(self):
self.items = []
def isEmpty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
def travel(self):
for i in self.items:
print(i, end=' ')
print('')
def push(self, item):
self.items.append(item)
# 这个是原来的pop函数,更名为pop1
def pop1(self):
self.items.pop(0)
# 需要改造下pop函数,使得这个函数有返回值
def pop(self):
return self.items.pop(0)
# 队列的基本功能的测试
q = Queue()
print(q.isEmpty()) # 应是True
for i in range(5):
q.push(i)
q.travel() # 0 1 2 3 4
for i in range(3):
q.pop1()
q.travel() # 3 4
print(q.size()) # 2
print('----------')
# 假设是用两个队列实现一个栈呢?
q1 = Queue()
q2 = Queue()
for i in range(10):
q1.push(i)
print('队列的出队顺序:', end=' ')
q1.travel()
print('栈的出栈顺序是:', end=' ')
while q1.size():
while q1.size() > 1:
# 出来的数先存到q2中,仅留一个数
item = q1.pop()
q2.push(item)
# 将仅留下的这个数出队并打印
print(q1.pop(), end=' ')
# 之后把两个队列互换
q1, q2 = q2, q1