关于队列和栈之间的转换

        我们知道,队列的特点是:先进先出(FIFO), 而栈的特点是:先进后出(FILO);

这两个数据结构的特点很像生活中的排列买票过程和坐电梯的过程(当然,是只有一个门打开的电梯);

在Python中,我们可以使用List来模拟这两个数据结构,可以通过限制List的行为来完成对这两种数据结构的模拟:让List只有append和默认pop的行为则模拟成栈,让List只有append和pop(0)的行为则模拟成队列;

 

 

那,当我们只有栈这种结构存在时,有没有办法得到一个队列呢,我们稍加思考就会发现:

在S1,S2两个栈处理后,也就是经过这两次push-> pop, 我们发现进入到S1中的a,b,c,从S2中出来的仍然是a,b,c;

所以,如果我们把S1,S2两个栈作为一个队列实现的暗箱,就完成了这两个栈实现队列的过程;

当然了,弄清了基本的原理,那么实现代码就很容易了。直接上代码:

# Python的代码实现

class QueueWithStacks:

         def __init__(self):

                 self.s1 = [ ]

                 self.s2 = [ ]

        # push很简单,让节点直接进入栈S1

        def push(self, e):

               self.s1.append(e)

        #  pop的操作要复杂点,原则上是将S1中的节点输入到S2,从S2中pop出来的元素一定是满足FIFO的顺序的

         def pop(self):

               if (len(self.s2) <= 0):

                    while (len(self.s1) > 0):  # 将S1中的元素依次Push到S2中;

                         t = self.s1.pop(len(self.s1)-1)

                         self.s2.append(t)

                assert(len(self.s2) > 0)   # 此时,需要保证S2中一定有元素,否则,逻辑上的队列是没有元素可以输出的;

               return self.s2.pop(len(self.s2)-1)

         # 显示当前封装队列的两个栈当前信息

         #def __repr__(self):

        #        print("s1:",self.s1)

        #       print("s2:",self.s2)

# 测试代码

q = QueueWithStacks()

q.push('a')

q.push('b')

q.push('c')

print(q.pop())

q.push('d')

print(q.pop())

print(q.pop())

print(q.pop())

 

在Q1,Q2两个队列中,我们可以使用一下的规则来模拟出一个栈:开始时,Q1进行push数据;以后,Q1与Q2不为空的进行push数据;pop时,将不为空的队列数据挨个push到空队列,直到剩一个元素为止,打印这个元素并删除;

由此,我们得到下面的Python代码:

class StackWithQueues(object):
  def __init__(self):
      self.stack1 = []
      self.stack2 = []
 
  # 刚开始,队列1进行push数据;以后,选择队列1与队列2不为空的进行push数据  
  def push(self,x):
      if len(self.stack1) == 0 and len(self.stack2) == 0:
          self.stack1.append(x)
      elif len(self.stack1) == 0 and len(self.stack2) > 0:
          self.stack2.append(x)
      elif len(self.stack2) == 0 and len(self.stack1) > 0:
          self.stack1.append(x)
      else:
          assert(1 == 0)
             
  # pop时,将不为空的队列数据挨个push到空队列,直到剩一个元素为止,打印这个元素并删除
  def pop(self):
     if len(self.stack1) > 0 and len(self.stack2) == 0:
         while len(self.stack1) > 1:
             self.stack2.append(self.stack1.pop(0))
         return self.stack1.pop(0)
     elif len(self.stack2) > 0 and len(self.stack1) == 0:
         while len(self.stack2) > 1:
             self.stack1.append(self.stack2.pop(0))
         return self.stack2.pop(0)
     else:
         assert(1==0)
 
  # 输出信息
#  def __repr__(self):
#      if self.stack1:
#          return self.stack1.__str__()
#      else:
#          return self.stack2.__str__()

# 测试代码

s = StackWithQueues()        
s.push(1)
s.push(2)
s.push(3)
print(s.pop())
print(s.pop())
print(s.pop())

这样的练习有助于更加灵活深入的理解数据结构的概念,所以在面试时经常出现。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值