程序员,你应该知道的数据结构之栈

小婷同学_4650

小婷同学_4650

2019-08-23

2445人浏览

转载

  数据结构中的栈不要与 Java 中的栈混淆,他们俩不是一回事,数据结构中的栈是一种受限制的线性表,栈具有先进后出、后进先出的特点,因为栈只允许访问最后一个数据项,即最后插入的数据项。也许你会有疑问,栈既然有这么多限制,为什么不用数组或者链表而使用栈?在开发中,我们有特定的场景,根据特定的场景去选用数据结构,栈的适用场景非常多,比如浏览器的前进与后退、字符串括号的合法性等,我们使用栈来实现就比较好,因为栈相对数组、链表来说对外提供的接口要少很多,接口少了,出错的概率就减少了,对风险的可控性就提高了。

推荐教程:PHP视频教程

实现一个栈

  从栈的定义中可以看出,栈主要有两个操作,一个是新增一条数据,我们叫做入栈,另一个是获取一条数据,称为出栈,下面两张图是入栈出栈示意图。

php81.png

php82.png

  栈的实现有两种方式,一种是基于数组实现的,我们叫作顺序栈,另一种是基于链表实现的,我们叫作链式栈。下面是两种栈的实现代码

基于数组的顺序栈

/**
 * 基于数组的顺序栈
 */
 public class ArrayStack {    // 栈最大容量
    private int maxSzie;    // 存放内容
    private String[] array;    // 栈顶元素
    private int top;    
    public ArrayStack(int size){      
      this.maxSzie = size;        
      this.array = new String[this.maxSzie];        
      this.top = 0;
    }  
      /**
     * 入栈操作
     *
     * @param data 数据
     * @return 0:入栈失败 1:入栈成功
     */
    public int push(String data) {      
      if (top == maxSzie) return 0;
        array[top] = data;
        top++;        
        return 1;
    }    
    /**
     * 出栈操作
     *
     * @return
     */
    public String pop() {     
       if (top == 0) return null;        
       return array[--top];
    }    
    /**
     * 获取栈顶元素
     *
     * @return
     */
    public String peek() {     
       return array[top - 1];
    }    
    /**
     * 判断栈是否为空
     * @return
     */
    public boolean isEmpty() {    
        return top == 0;
    }
}

基于链表的链式栈

/**
 * 基于链表的链式栈
 */public class LinkStack {    // 始终指向栈的第一个元素
    private Node top = null;    
    /**
     * 压栈
     *
     * @param data
     * @return
     */
    public int push(String data) {
        Node node = new Node(data);        
        if (top == null) {
            top = node;
        } else {
            node.next = top;
            top = node;
        }       
         return 1;
        }   
     /**
     * 出栈
     *
     * @return
     */
    public String pop() {     
       if (top == null) return null;
        String data = top.getData();
        top = top.next;       
         return data;
    }   
     /**
     * 节点信息
     */
    private static class Node {      
      private String data;      
      private Node next;        
      public Node(String data) {        
          this.data = data;          
          this.next = null;
        }       
      public String getData() {          
        return this.data;
        }
    }
}

  栈的实现比较简单,因为栈涉及的操作不多,主要就入栈和出栈两个操作。

栈的应用

检测字符串括号的合法性

快面
快面

一款AI办公效率工具,主要用于Kuaimian 是全流程 AI 面试助手:支持 AI 简历优化、AI 模拟面试,并在真实面试与在线笔试过程中提供实时 AI 辅助,适合需要提升相关任务效率的用户。

下载

  我们有时候需要检测字符串括号的合法性,即一个左括号需要匹配一个右括号,这个我们可以使用栈来实现。我们可以从一个合法的括号来理解为什么使用栈?如果括号使用合法,最后一个左括号跟第一个右括号是匹配的,倒数第二个左括号和第二个右括号匹配的,以此类推,这符合我们栈的特性先进后出。

  假设我们有三种括号:圆括号 ()、方括号 [] 和花括号{},我们使用栈来检测括号的合法性。我们将左括号全部压栈,当出现右括号时,我们就进行匹配,这时候有如下三种情况:

  ●栈为空,说明没有左括号,括号使用不合法

  ●栈中取出来的左括号跟右括号不匹配,括号使用不合法

  ●栈中取出的左括号跟右括号匹配,括号使用暂时合法

  当整个字符串都扫描完成后,检测栈中是否还有值,如果栈为空,则说明括号使用合法,反正,则括号使用不合法。

实现代码

public static boolean BracketChecker(String data) {
    char[] chars = data.toCharArray();
    ArrayStack stack = new ArrayStack(chars.length);    
    for (char ch : chars) {
            switch (ch){
                        case '{':            
                        case '[':            
                        case '(':
                                stack.push(ch);                
                                break;            
                         case '}':            
                         case ']':            
                         case ')':             
                                if (!stack.isEmpty()){                 
                                   char ch1 = stack.pop();                    
                                   if ((ch=='}' && ch1 !='{')
                                        ||(ch==']' && ch1 !='[')
                                        ||(ch==')' && ch1 !='(')

                    ){                 
                           return false;
                    }
                }else {    
                           return false;
                }     
                break;            
        default:            
            break;
        }
    }   
    return stack.isEmpty();
}

浏览器前进、后退功能

  我们使用浏览器都知道,浏览器可以前进、后退功能,浏览器的前进后退也符合栈的特点,我们最先访问的网页肯定要最后才能倒回去。我们一起来看看栈怎么实现这个功能?

  我们需要定义两个栈,我们将首次访问的页面压栈到第一个栈中,当点击后退时,从第一个栈中取出数据放入到第二个栈,当点击前进按钮时,从第二个栈取出数据放入第一个栈。当第一个栈没有数据时,说明没有页面可以点击后退了,当第二个栈没有数据时,说明没有页面可以点击前进了。这样我们就通过栈实现了浏览器前进、后退功能。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

2026.11.02

0

14

Uvicorn使用教程
Uvicorn使用教程

本专题汇总了Uvicorn使用教程与启动运行指南,涵盖其作为Python ASGI服务器的定位与特点,以及命令行启动(uvicorn main:app --reload)、参数配置(host/port/workers)、程序内嵌运行与Gunicorn结合部署等核心用法。同时整理了热重载调试、日志配置与生产环境部署优化等技巧,助你快速掌握Uvicorn的运行与配置。

2026.11.02

0

17

Uvicorn安装配置教程
Uvicorn安装配置教程

本专题汇总了Uvicorn的安装配置教程与部署指南,涵盖通过pip安装Uvicorn、启动FastAPI/Starlette应用、开发模式热重载(--reload)及多进程工作模式配置等核心操作。同时整理了结合Gunicorn的生产部署方案、HTTPS与反向代理配置及性能调优技巧,助你快速完成Uvicorn服务的安装与上线部署。

2026.11.02

0

17

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

100

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

80

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

240

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

140

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

140

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

100

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
LLVM Programmer’s Manual
LLVM Programmer’s Manual

共0课时 | 0人学习

MongoDB 教程
MongoDB 教程

共17课时 | 6.5万人学习