栈与队列

Posted eliwang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈与队列相关的知识,希望对你有一定的参考价值。

一、栈

  • 特性:

    • 先进后出

    • 从栈顶向栈底添加元素,从栈顶取元素
  • 栈的操作

    • Stack() :创建一个新的空栈
    • push(item) :添加一个新的元素item到栈顶
    • pop() :弹出栈顶元素
    • peek() :返回栈顶元素
    • is_empty(): 判断栈是否为空
    • size(): 返回栈的元素个数
  • 栈的实现

    class Stack:
        """"""
        def __init__(self):
             self.items = []
    
        def is_empty(self):
            """判断是否为空"""
            return self.items == []
    
        def push(self, item):
            """添加元素"""
            self.items.append(item)
    
        def pop(self):
            """弹出元素"""
            return self.items.pop()
    
        def peek(self):
            """返回栈顶元素"""
            return self.items[len(self.items)-1]
    
        def size(self):
            """返回栈的大小"""
            return len(self.items)
    
    if __name__ == "__main__":
        stack = Stack()
        stack.push("hello")
        stack.push("world")print (stack.size())
        print (stack.peek())
        print (stack.pop())

二、队列

  • 特性:

    • 先进先出
    • 只允许从队尾插入元素,从队头取元素
  • 操作:

    • Queue() :创建一个空的队列
    • enqueue(item) :往队列中添加一个item元素
    • dequeue() :从队列头部删除一个元素
    • is_empty() :判断一个队列是否为空
    • size() :返回队列的大小
  • 队列实现:

    class Queue:
        \'\'\'队列\'\'\'
        def __init__(self):
            self.items = []
    
        def enqueue(self,item):
            \'\'\'入队列\'\'\'
            self.items.insert(0,item)
    
        def dequeue(self):
            \'\'\'出队列\'\'\'
            return self.items.pop()
    
        def is_empty(self):
            \'\'\'判空\'\'\'
            return self.items == []
    
        def size(self):
            \'\'\'大小\'\'\'
            return len(self.items)
    
    if __name__ == "__main__":
        q = Queue()
        q.enqueue("hello")
        q.enqueue("world")
        print(q.size())
        print(q.dequeue())
  • 案例

    • 烫手的山芋:
      • 6个孩子围成一个圈,排列顺序由自己指定。第一个孩子手里有一个烫手的山芋,需要在计时器计时开始1秒后传递给下一个孩子,以此类推。规则是:计时器每计时7秒时,就会淘汰手里有山芋的孩子,该游戏直到剩下最后一个孩子结束,该孩子获胜。请用队列实现该游戏策略,排在第几个孩子最终获胜。
    • 分析:
      • 队列特性:先进先出,并且只能从队尾插入数据,从队头取数据。
      • 第1秒时,山芋在第1个孩子手里,第2秒时在第2个孩子手里,以此类推,第7秒时,该轮游戏中山芋被传递了6次
      • 可以将手里有山芋的孩子始终放在队头位置:每传递一次,队头孩子出队列,然后再入队列,每轮结束时,队头孩子出队列
    • 代码实现:
      # coding:utf-8
      
      class Queue:
          \'\'\'队列\'\'\'
          def __init__(self):
              self.items = []
      
          def enqueue(self,item):
              \'\'\'入队列\'\'\'
              self.items.insert(0,item)
      
          def dequeue(self):
              \'\'\'出队列\'\'\'
              return self.items.pop()
      
          def is_empty(self):
              \'\'\'判空\'\'\'
              return self.items == []
      
          def size(self):
              \'\'\'大小\'\'\'
              return len(self.items)
      
      def shanyu_game():
          \'\'\'烫手的山芋游戏\'\'\'
      
          kids = [1,2,3,4,5,6] #1-6分别表示一开始对应位置上的孩子
          q = Queue()
          for kid in kids:
              q.enqueue(kid)
          while q.size() > 1:
              for i in range(6):
                  kid = q.dequeue() #出队列
                  q.enqueue(kid) #入队列
              q.dequeue()
          print(\'第%s个孩子获胜\'%q.dequeue())
      
      
      if __name__ == "__main__":
         shanyu_game()

       运行结果:第5个孩子获胜

 三、双端队列

  • 特性

    • 是一种具有队列和栈的性质的数据结构。
    • 可以在队列任意一端入队和出队。
  • 操作

    • Deque() :创建一个空的双端队列
    • add_front(item) :从队头加入一个item元素
    • add_rear(item) :从队尾加入一个item元素
    • remove_front() :从队头删除一个item元素
    • remove_rear(): 从队尾删除一个item元素
    • is_empty(): 判断双端队列是否为空
    • size(): 返回队列的大小
  • 实现

    class Deque:
        \'\'\'双端队列\'\'\'
    
        def __init__(self):
            self.items = []
    
        def add_front(self,item):
            \'\'\'队头插入元素\'\'\'
            self.items.insert(0,item)
    
        def add_rear(self,item):
            \'\'\'队尾插入元素\'\'\'
            self.items.append(item)
    
        def remove_front(self):
            \'\'\'队头删除元素\'\'\'
            return self.items.pop(0)
    
        def remove_rear(self):
            \'\'\'队尾删除元素\'\'\'
            return self.items.pop()
    
        def size(self):
            \'\'\'返回队列大小\'\'\'
            return len(self.items)
    
    if __name__ == \'__main__\':
        d = Deque()
        d.add_front(\'a\')
        d.add_front(\'b\')
        d.add_rear(\'c\')
        d.add_rear(\'d\')
        print(d.remove_front())
        print(d.remove_rear())
        print(d.size())
  • 案例

    • 回文检查:判断字符串首尾字符是否相同,例如madam,toot
    • 代码实现:
      # coding:utf-8
      class Deque:
          \'\'\'双端队列\'\'\'
      
          def __init__(self):
              self.items = []
      
          def add_front(self,item):
              \'\'\'队头插入元素\'\'\'
              self.items.insert(0,item)
      
          def add_rear(self,item):
              \'\'\'队尾插入元素\'\'\'
              self.items.append(item)
      
          def remove_front(self):
              \'\'\'队头删除元素\'\'\'
              return self.items.pop(0)
      
          def remove_rear(self):
              \'\'\'队尾删除元素\'\'\'
              return self.items.pop()
      
          def size(self):
              \'\'\'返回队列大小\'\'\'
              return len(self.items)
      
      def palindrome_checker(item):
          \'\'\'回文检查器\'\'\'
          d = Deque()
          for i in item:
              d.add_rear(i)
          while d.size() > 1:
              start = d.remove_front()
              end = d.remove_rear()
              #判断首位字符是否相等,不相等即返回False
              if start != end:
                  return False
          return True
      
      if __name__ == \'__main__\':
          print(palindrome_checker(\'hello\'))
          print(palindrome_checker(\'abbccbba\'))
          print(palindrome_checker(\'abcdcba\'))

 

四、使用栈实现队列

  • 分析:

    • 使用栈实现队列,即实现先进先出的特性
    • 可以采用两个栈来实现
      • 栈A提供入队列功能
      • 栈B提供出队列功能
        • 若栈B为空,则先将栈A中的数据依次弹出,放入栈B,再弹出栈B的最后一个数据
        • 若栈B不为空,则直接弹出栈B的最后一个数据
    • 代码实现:
      # coding:utf-8
      
      class Stack:
          """"""
          def __init__(self):
               self.items = []
      
          def is_empty(self):
              """判断是否为空"""
              return self.items == []
      
          def push(self, item):
              """添加元素"""
              self.items.append(item)
      
          def pop(self):
              """弹出元素"""
              return self.items.pop()
      
          def peek(self):
              """返回栈顶元素"""
              return self.items[len(self.items)-1]
      
          def size(self):
              """返回栈的大小"""
              return len(self.items)
      
      class MyQueue:
          \'\'\'栈实现队列\'\'\'
          def __init__(self):
              self.A = Stack()
              self.B = Stack()
      
          def push(self,item):
              \'\'\'入队列\'\'\'
              self.A.push(item)
      
          def pop(self):
              \'\'\'出队列\'\'\'
              if self.B.is_empty():
                  while not self.A.is_empty():
                      self.B.push(self.A.pop())
              return self.B.pop()
      
      if __name__ == \'__main__\':
          q = MyQueue()
          q.push(\'a\')
          q.push(\'b\')
          q.push(\'c\')
          print(q.pop())
          print(q.pop())
          print(q.pop())

       

 

以上是关于栈与队列的主要内容,如果未能解决你的问题,请参考以下文章

栈与队列:循环队列算法+可执行代码

[算法] leetcode栈与队列相关题目详解

数据结构《三》栈与队列的实现

栈与队列试题中的操作代码

从今天开始好好学数据结构02栈与队列

数据结构栈与队列