返回

数据结构基础漫谈(一):栈,为你清晰解读“后进先出”!

前端

后进先出——栈的定义与特性

栈是一种遵从后进先出(LIFO,Last In First Out)原则的数据结构。它类似于日常生活中叠盘子或放石子,最后放进去的元素会最先被拿出来。栈具有以下特点:

  • 只能在栈顶进行插入和删除操作。
  • 栈顶的元素称为栈顶元素。
  • 栈底的元素称为栈底元素。
  • 栈中的元素只能按顺序访问。

栈的典型应用场景

栈在计算机科学和编程中有着广泛的应用,其中一些典型场景包括:

  • 浏览器历史记录:浏览器使用栈来存储历史记录,用户可以按顺序访问浏览过的网页。
  • 函数调用:函数调用时,参数和局部变量会被压入栈中,当函数执行完毕后,这些数据会被弹出栈。
  • 表达式计算:后缀表达式(又称逆波兰表示法)的计算可以使用栈来实现。
  • 递归算法:递归算法在执行过程中,函数调用会被压入栈中,当递归结束时,这些调用会被弹出栈。

栈的实现——揭秘数据结构之谜

栈的数据结构可以有多种实现方式,常见的有数组和链表。

  • 数组实现: 数组实现栈是最简单的方式,它使用一个数组来存储数据,并使用两个指针(栈顶指针和栈底指针)来标记栈的边界。
  • 链表实现: 链表实现栈也比较常见,它使用一个链表来存储数据,并使用一个指针指向栈顶元素。

栈的代码实现——C语言

以下是用 C 语言实现的栈:

#include <stdio.h>
#include <stdlib.h>

// 定义栈的结构
typedef struct Stack
{
    int *arr;
    int top;
    int capacity;
} Stack;

// 创建栈
Stack *createStack(int capacity)
{
    Stack *stack = (Stack *)malloc(sizeof(Stack));
    stack->arr = (int *)malloc(sizeof(int) * capacity);
    stack->top = -1;
    stack->capacity = capacity;
    return stack;
}

// 入栈
void push(Stack *stack, int data)
{
    if (stack->top == stack->capacity - 1)
    {
        printf("Stack overflow!\n");
        return;
    }
    stack->arr[++stack->top] = data;
}

// 出栈
int pop(Stack *stack)
{
    if (stack->top == -1)
    {
        printf("Stack underflow!\n");
        return -1;
    }
    return stack->arr[stack->top--];
}

// 获取栈顶元素
int peek(Stack *stack)
{
    if (stack->top == -1)
    {
        printf("Stack is empty!\n");
        return -1;
    }
    return stack->arr[stack->top];
}

// 检查栈是否为空
int isEmpty(Stack *stack)
{
    return stack->top == -1;
}

// 检查栈是否已满
int isFull(Stack *stack)
{
    return stack->top == stack->capacity - 1;
}

// 打印栈中的元素
void printStack(Stack *stack)
{
    if (isEmpty(stack))
    {
        printf("Stack is empty!\n");
        return;
    }
    printf("Stack: ");
    for (int i = stack->top; i >= 0; i--)
    {
        printf("%d ", stack->arr[i]);
    }
    printf("\n");
}

int main()
{
    // 创建一个容量为 5 的栈
    Stack *stack = createStack(5);

    // 入栈
    push(stack, 1);
    push(stack, 2);
    push(stack, 3);
    push(stack, 4);
    push(stack, 5);

    // 打印栈中的元素
    printStack(stack);

    // 出栈
    pop(stack);
    pop(stack);

    // 打印栈中的元素
    printStack(stack);

    // 获取栈顶元素
    int top = peek(stack);
    printf("Top of the stack: %d\n", top);

    // 检查栈是否为空
    if (isEmpty(stack))
    {
        printf("Stack is empty!\n");
    }
    else
    {
        printf("Stack is not empty!\n");
    }

    // 检查栈是否已满
    if (isFull(stack))
    {
        printf("Stack is full!\n");
    }
    else
    {
        printf("Stack is not full!\n");
    }

    return 0;
}

通过这篇文章,我们对栈的数据结构和其实现方式有了更加深入的了解。栈在计算机科学和编程中有着广泛的应用,掌握栈的原理和实现方法可以帮助我们解决许多实际问题。