【算法题】使用两个栈实现一个队列

本文介绍了一种利用两个栈实现队列数据结构的方法,并通过逐步优化改进,减少资源浪费,提高效率。首先采用两个栈轮流倒换的方式实现队列的基本功能,随后优化入队和出队操作流程。

思路 ①

一个最憨厚的思路就是,两个栈一个作为数据栈,一个作为临时栈,使用数据栈来存储队列数据。

入队列和入栈行为完全相同。

出队列时,使用另一个栈临时将栈内数据倒序,返回栈顶数据后。 将数据存回数据栈,以便不影响后续的入队列数据。

 定义一个栈结构

class Stack:
    def __init__(self):
        self.data = []

    def push(self, v):
        self.data.append(v)

    def pop(self):
        return self.data.pop()

    def is_empty(self):
        return self.data == []

队列代码实现

class Queue:
    def __init__(self):
        self.stack1 = Stack()
        self.stack2 = Stack()

    def push(self, v):
        self.stack1.push(v)

    def pop(self):
        # 将数据栈中数据倒入临时栈
        while not self.stack1.is_empty():
            self.stack2.push(self.stack1.pop())
        # 弹出栈顶数据
        top = self.stack2.pop()
        # 将临时栈中数据倒入数据栈
        while not self.stack2.is_empty():
            self.stack1.push(self.stack2.pop())
        return top

问题:

连续多次pop数据时,需要反复将数据栈数据导入临时栈,浪费资源。

改进:

两个栈一个作为入口栈处理入队列, 一个命名为出口栈处理出队列。

数据出队列时,将入口栈中的数据导入出口栈,然后将顶部数据出栈。

数据入队列时,将出口栈中可能存在的数据压回入口栈,然后将新数据入栈

 由于没有将数据导回入口栈,对于后续的出队列操作,可以直接在出口栈继续进行。如队列要弹出数据2,直接再出口栈pop即可。

 入队列时,要将之前可能存在于出口栈的数据导回,然后将数据放到队列末尾,如果有连续的入栈操作,只需导回一次即可。

代码实现:

class Queue:
    def __init__(self):
        self.stack_in = Stack()
        self.stack_out = Stack()

    def push(self, v):
        # 出口栈中如果有数据,将其倒入入口栈
        while not self.stack_out.is_empty():
            self.stack_in.push(self.stack_out.pop())
        # 新数据入栈
        self.stack_in.push(v)
  
    def pop(self):
        # 入口栈中如果有数据,将其导入出口栈
        while not self.stack_in.is_empty():
            self.stack_out.push(self.stack_in.pop())
        return self.stack_out.pop()

 思路②

 改进的思路,将连续的入队列或者出队列操作不再进行两个栈的数据转换。但入队列时还是要关注出口栈中的数据。下面再次进行改进

两个栈依然一个作为入口栈处理入队列, 一个命名为出口栈处理出队列。

数据入队列时,和入栈行为相同,直接将数据压入入口栈。

数据出队列时,检查出口栈中是否有数据,如果有数据,则直接将顶部数据返回。如果没有数据,尝试将入口栈中的数据导入出口栈,然后将顶部数据返回。

为了更加直观的展示,下面图中将栈横着放。

① 数据入队列,将数据 1 2 3 依次放入入口栈

②  数据出队列, 发现出口栈中没有数据,将入口栈中的数据 [1, 2, 3] 依次压入出口栈,出口栈中数据为 [3, 2, 1],  执行出队列,将出口栈顶部的 1 返回。

③ 后续的入队列和出队列操作,和前面步骤相同。新的数据入队列则直接压入入口栈。新的出队列请求直接从出口栈返回数据,直到出口栈为空,则再次将入口栈中的数据导入到出口栈

 代码如下:

class Queue:
    def __init__(self):
        self.stack_in = Stack()
        self.stack_out = Stack()

    def push(self, v):
        self.stack_in.push(v)

    def pop(self):
        if self.stack_out.is_empty():
            while not self.stack_in.is_empty():
                self.stack_out.push(self.stack_in.pop())
        return self.stack_out.pop()

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值