(Python3)数据结构——08.队列之用队列实现一个栈

前言

  • 有Python基础
  • 最好是学过数据结构的栈和队列

原理

  • 队列和栈的详细信息请参见链接:
  1. 队列 :https://blog.csdn.net/sf9898/article/details/104941655
  2. :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
  • 结果

在这里插入图片描述

发布了28 篇原创文章 · 获赞 12 · 访问量 4123

猜你喜欢

转载自blog.csdn.net/sf9898/article/details/104992843
今日推荐