数据结构的栈

简介: 栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。

栈(Stack)是一种重要的数据结构,它具有后进先出(Last In First Out,LIFO)的特性,就像一个只能在一端进行插入和删除操作的容器。以下是关于栈的详细介绍:

基本概念

  • 栈顶:栈的一端被称为栈顶,所有的插入和删除操作都在栈顶进行。
  • 栈底:与栈顶相对的另一端是栈底,栈底的元素是最先被插入到栈中的元素。

操作

  • 入栈(Push):将一个元素添加到栈顶的操作。例如,若有一个空栈,依次将元素1、2、3入栈,此时栈顶元素为3,栈底元素为1。
  • 出栈(Pop):将栈顶元素从栈中移除的操作。对于上述栈,执行一次出栈操作后,栈顶元素变为2,栈底元素仍为1。
  • 查看栈顶元素(Peek):只获取栈顶元素的值,但不移除它。在上述栈中,执行Peek操作将返回3,但栈的状态不变。

实现方式

  • 顺序存储实现(数组):可以使用数组来实现栈。定义一个数组来存储栈中的元素,并使用一个变量来记录栈顶的位置。入栈操作时,将元素放入数组中栈顶位置的下一个位置,并更新栈顶变量;出栈操作时,将栈顶位置的元素移除,并更新栈顶变量。以下是一个简单的Java示例:

    class ArrayStack {
         
      private int[] stack;
      private int top;
    
      public ArrayStack(int capacity) {
         
          stack = new int[capacity];
          top = -1;
      }
    
      public void push(int item) {
         
          if (top == stack.length - 1) {
         
              // 栈已满,可进行扩容操作
              System.out.println("Stack is full.");
              return;
          }
          stack[++top] = item;
      }
    
      public int pop() {
         
          if (top == -1) {
         
              // 栈为空
              System.out.println("Stack is empty.");
              return -1;
          }
          return stack[top--];
      }
    
      public int peek() {
         
          if (top == -1) {
         
              // 栈为空
              System.out.println("Stack is empty.");
              return -1;
          }
          return stack[top];
      }
    }
    
  • 链式存储实现:也可以使用链表来实现栈。定义一个链表节点类,每个节点包含数据域和指向下一个节点的指针。栈顶指针指向链表的头节点,入栈操作时,创建一个新节点,并将其插入到链表的头部,使其成为新的栈顶;出栈操作时,移除链表的头节点,并更新栈顶指针。以下是一个简单的Java示例:
    ```java
    class Node {
    int data;
    Node next;

    public Node(int data) {

      this.data = data;
      this.next = null;
    

    }
    }

class LinkedStack {
private Node top;

public void push(int item) {
    Node newNode = new Node(item);
    newNode.next = top;
    top = newNode;
}

public int pop() {
    if (top == null) {
        // 栈为空
        System.out.println("Stack is empty.");
        return -1;
    }
    int data = top.data;
    top = top.next;
    return data;
}

public int peek() {
    if (top == null) {
        // 栈为空
        System.out.println("Stack is empty.");
        return -1;
    }
    return top.data;
}

}
```

应用场景

  • 函数调用栈:在程序执行过程中,当一个函数被调用时,系统会为该函数创建一个栈帧,并将其压入函数调用栈。栈帧中包含了函数的参数、局部变量、返回地址等信息。当函数执行完毕后,对应的栈帧会被弹出,程序控制返回到调用该函数的位置。这种机制实现了函数的嵌套调用和递归调用。
  • 表达式求值:栈可以用于实现表达式求值算法,如后缀表达式求值。将中缀表达式转换为后缀表达式后,利用栈来存储操作数和进行运算,可以方便地计算表达式的值。
  • 括号匹配:用于检查表达式中的括号是否匹配。遍历表达式,遇到左括号时将其入栈,遇到右括号时,检查栈顶元素是否为相应的左括号,若是则出栈,否则表达式括号不匹配。
  • 浏览器的后退和前进功能:浏览器的历史记录可以使用两个栈来实现。一个栈用于存储用户访问过的页面,当用户点击后退按钮时,从该栈中弹出页面;另一个栈用于存储用户点击前进按钮时需要访问的页面,当用户点击前进按钮时,从另一个栈中弹出页面。

栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。

相关文章
|
16天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
90 9
|
7天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
15 1
|
12天前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
14天前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
42 4
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
30 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
18天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
初步认识栈和队列
初步认识栈和队列
58 10
|
1月前
数据结构(栈与列队)
数据结构(栈与列队)
17 1
|
1月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
46 3
|
1月前
|
存储 JavaScript 前端开发
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
68 1