返回

队列的典型题:栈实现队列、双端队列,栈实现队列、双端队列思路及代码演示

前端

栈和队列:灵活的数据结构的有趣组合

在计算机科学的世界中,数据结构是用来组织和存储数据的基本构建块。其中最基本的数据结构之一就是栈和队列。

栈:后进先出

想象一下一个弹簧床垫。当您向床垫添加更多物品时,它们会压在已经在那里的物品上。当您取回物品时,您会从顶部取回最近添加的物品。这就是栈的工作原理。最后一个进入栈的元素是第一个出来的元素,这被称为后进先出(LIFO)。

队列:先进先出

另一方面,队列就像排队等候的队列。当人们加入队列时,他们会在队伍的后面排队。当人们离开队列时,他们会从队伍的前面离开。这就是队列的工作原理。第一个进入队列的元素是第一个出来的元素,这被称为先进先出(FIFO)。

使用栈实现队列

有时,您可能需要使用栈来实现队列。我们可以使用两个栈来做到这一点。一个栈用作输入栈,另一个栈用作输出栈。当您向队列添加元素时,您将其压入输入栈。当您从队列中删除元素时,您从输出栈中弹出元素。如果输出栈为空,您将输入栈中的所有元素弹出并压入输出栈。

class Queue:
    def __init__(self):
        self.input_stack = []
        self.output_stack = []

    def enqueue(self, item):
        self.input_stack.append(item)

    def dequeue(self):
        if not self.output_stack:
            while self.input_stack:
                self.output_stack.append(self.input_stack.pop())

        return self.output_stack.pop()

    def is_empty(self):
        return not self.input_stack and not self.output_stack

使用栈实现双端队列

双端队列(又称 deque)是一种可以在两端添加和删除元素的数据结构。我们可以使用两个栈来实现双端队列。一个栈用作左端栈,另一个栈用作右端栈。当您向双端队列的左侧添加元素时,您将其压入左端栈。当您向双端队列的右侧添加元素时,您将其压入右端栈。当您从双端队列的左侧删除元素时,您从左端栈中弹出元素。当您从双端队列的右侧删除元素时,您从右端栈中弹出元素。

class Deque:
    def __init__(self):
        self.left_stack = []
        self.right_stack = []

    def append_left(self, item):
        self.left_stack.append(item)

    def append_right(self, item):
        self.right_stack.append(item)

    def pop_left(self):
        if not self.left_stack:
            while self.right_stack:
                self.left_stack.append(self.right_stack.pop())

        return self.left_stack.pop()

    def pop_right(self):
        if not self.right_stack:
            while self.left_stack:
                self.right_stack.append(self.left_stack.pop())

        return self.right_stack.pop()

    def is_empty(self):
        return not self.left_stack and not self.right_stack

结论

栈和队列是计算机科学中必不可少的数据结构。它们具有不同的特性,使其适合不同的应用程序。有时,我们可能需要使用栈来实现队列或双端队列。使用两个栈,我们可以创建具有与原始数据结构相同行为的灵活数据结构。

常见问题解答

  • 为什么要使用栈来实现队列或双端队列?
    • 在某些情况下,使用栈来实现这些数据结构可能更方便或更高效。例如,如果您已经有一个栈库,并且不想引入额外的依赖项,则使用栈来实现队列或双端队列可能是更有意义的。
  • 栈实现的队列或双端队列与原始数据结构有什么区别?
    • 栈实现的队列或双端队列的行为与原始数据结构相同。然而,它们可能具有不同的时间复杂度或空间复杂度。
  • 什么时候应该使用栈实现的队列或双端队列?
    • 当您已经拥有一个栈库并且不想引入额外的依赖项时,或者当您需要使用队列或双端队列的特定特性时,就可以使用栈实现的队列或双端队列。
  • 栈实现的队列或双端队列有哪些优势?
    • 栈实现的队列或双端队列的一个优势是,它们易于实现。您只需使用两个栈即可实现它们,而无需引入额外的复杂性。
  • 栈实现的队列或双端队列有哪些缺点?
    • 栈实现的队列或双端队列的一个缺点是,它们的某些操作可能比原始数据结构慢。例如,从栈实现的队列中删除元素可能需要 O(n) 时间,而从原始队列中删除元素需要 O(1) 时间。