栈:后进先出的线性表,如何实现增删查?

本文主要讲解栈这种数据结构,它是一种后进先出(LIFO)的线性表,并探讨如何实现栈的增加、删除、查找操作。 由于栈的特殊性,通常不涉及“改”操作,更多关注的是入栈和出栈。

栈的定义

栈(Stack)是一种特殊的线性表,它只允许在表的一端进行插入和删除操作。 这一端被称为栈顶(top),另一端被称为栈底(bottom)。 当栈中没有元素时,称为空栈。

栈的特点是后进先出(Last In First Out, LIFO),也就是说,最后进入栈的元素最先出去。

栈的基本操作

栈的基本操作包括:

  • 入栈(Push):将一个新元素放入栈顶。
  • 出栈(Pop):从栈顶移除一个元素。
  • 查看栈顶元素(Peek/Top):获取栈顶元素的值,但不移除它。
  • 判断栈是否为空(isEmpty):检查栈中是否还有元素。
  • 获取栈的大小(Size):返回栈中元素的个数。

栈的实现方式

栈可以用数组或链表来实现。

数组实现

用数组实现栈,需要指定栈的大小,并且需要一个指针指向栈顶。

优点:

  • 实现简单。
  • 访问栈顶元素的时间复杂度为O(1)。

缺点:

  • 栈的大小固定,容易造成空间浪费或溢出。
  • 插入和删除操作需要移动元素,时间复杂度为O(n) (虽然通常只在栈顶操作,复杂度近似O(1),但极端情况下,例如需要扩容时,复杂度会变为O(n))

链表实现

用链表实现栈,不需要指定栈的大小,并且需要一个指针指向栈顶。

优点:

  • 栈的大小可以动态扩展。
  • 插入和删除操作不需要移动元素,时间复杂度为O(1)。

缺点:

  • 需要额外的空间存储指针。
  • 访问栈顶元素的时间复杂度为O(1)。

栈的应用

栈在计算机科学中有很多应用,例如:

  • 函数调用栈:用于保存函数调用时的参数、返回地址等信息。
  • 表达式求值:用于将中缀表达式转换为后缀表达式,并进行求值。
  • 括号匹配:用于检查括号是否匹配。
  • 浏览器的前进后退功能:后退时,从栈顶取出最近访问的页面。
  • Undo/Redo 功能: 撤销和重做操作。

栈的增删查

  • 增加(入栈 Push): 将元素添加到栈顶。
  • 删除(出栈 Pop): 移除栈顶元素。
  • 查(查看栈顶元素 Peek/Top): 获取栈顶元素,但不移除。 需要注意的是,栈主要关注栈顶元素,查找特定元素通常不是栈的主要用途。如果要查找栈中特定元素,需要出栈直到找到目标元素或栈为空。

代码示例 (Python - 数组实现)

class Stack:
    def __init__(self, capacity):
        self.capacity = capacity
        self.stack = [None] * capacity
        self.top = -1

    def is_empty(self):
        return self.top == -1

    def is_full(self):
        return self.top == self.capacity - 1

    def push(self, item):
        if self.is_full():
            print("Stack is full")
            return
        self.top += 1
        self.stack[self.top] = item

    def pop(self):
        if self.is_empty():
            print("Stack is empty")
            return None
        item = self.stack[self.top]
        self.stack[self.top] = None # Optional: Clear the reference
        self.top -= 1
        return item

    def peek(self):
        if self.is_empty():
            print("Stack is empty")
            return None
        return self.stack[self.top]

    def size(self):
        return self.top + 1

# Example Usage:
s = Stack(5)
s.push(1)
s.push(2)
s.push(3)

print(s.peek()) # Output: 3
print(s.pop())  # Output: 3
print(s.size()) # Output: 2