栈和队列详细讲解+算法动画

news2024/9/23 13:30:11

栈和队列

栈stack

  • 栈也是一种线性结构
  • 相比数组,栈对应的操作数数组的子集
  • 只能从一端添加元素,也只能从一端取出元素
  • 这一端称为栈顶
  • 栈是一种后进先出的数据结构
  • Last in Firt out(LIFO)
  • 在计算机的世界里,栈拥有者不可思议的作用

栈的应用

  • 无处不在的undo操作(撤销)
    • 沉迷 学习 不法
  • 程序调用的系统栈
    • 从A函数调用B函数,B函数在调用C函数
    • A2,表示进行到A函数的第二行

image-20230309104046919

当一个子过程可以自动回到上层调用继续执行的原因,因为有系统栈去记录每一个中断的点。子过程的调用实现机理就是如此。对于递归的理解会在后续介绍。

栈的实现

Stack

  • void push(E)
  • E pop()
  • E peek()
  • int getSize()
  • boolean isEmpty()

从用户的角度看,支持这些操作就好

具体底层实现,用户不关心

实际底层有多种实现方式

image-20230309104510714

采用多态的方式

public Interface Stack<E>{
    int getSize();
    boolean isEmpty();
    void push(E e);
    E pop();
    E peek();
}
public class ArrayStack<E> implements Stack<E>{
    Array<E> array;
    public ArrayStack(int getCapacity){
        array = new Array<>(capacity);
    }
    public ArrayStack(){
        array = new Array<>();
    }
    @Override
    int getSize(){
    	return array.getSise;    
    }
    @Override
    boolean isEmpty(){
        return array.isEmpty();
    }
    @Override
    public int getCapacity(){
        return array.getCapacity();
    }
    @Override
    void push(E e){
        arraty.addLasy(e);
    }
    @Override
    E pop(){
        array.removeLast();
    }
    @Override
    E peek(){
        return array.getLast();
    }
    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append("Stack: ");
        res.append("[]");
        for(int i  = 0 ; i < arr.getSize();i++){
            res.append(array.get(i));
            if(i!=array.getSize()-1)
                res.append(", ");
        }
        res.append("] top");
        return res.toString();
    }
}
对于array新加如下方法
public E getLast(){
    return get(size-1);
}
public E getFirst(){
    return get(0);
}

栈的另一个应用,括号匹配

image-20230309110103797

image-20230309110156250

这是二十家大公司对于该题的面试形式

栈顶元素反映了在嵌套的层次关系中,最近的需要匹配的元素

Class Solution{
    public boolean isValid(String s){
        Stack<Character> stack = new Stack<>();
        for(int i  = 0 ; i <s.length();i++)
            char c = s.charAt(i);
        	if(c=='('||c=='['||c=='{')
                stack.push(c);
        	else{
                if(stack.isEmpty())return false;
                char topChar = stack.pop();
                if(c==')'&&topChar!='(')return false;
                if(c==']'&&topChar!='[')return false;
                if(c=='}'&&topChar!='{')return false;
            }
        return stack.isEmpty();
    }
}

队列

  • 队列也是一种线性结构

  • 相比数组,队列对应的操作是数组的子集

  • 只能从一端添加元素,从另一端取出元素

  • 队列是一种先进先出的数据结构(先到先得)

  • First In First Out(FIFO)

Queue<E>
- void enqueue(E)//入队
- E dequeue()//出队
- E getFront()//获取队首元素
- int getSize()
- boolean isEmpty()//是否为空
image-20230309113245830
public interface Queue<E>{
    void enqueue(E)//入队
	E dequeue()//出队
	E getFront()//获取队首元素
	int getSize()
	boolean isEmpty()//是否为空
}
public class ArrayQueue<E> implements Queue<E>{
    private Array<E> array;
    public ArrayQueue(int capacity){
        array = new Array<>(capacity);
        
    }
    public ArrayQueue(){
        array = new Array<>();
    }
    @Override
    public int getSize(){
        return array.getSize();
    }
    @Override
    public int isEmpty(){
        return array.isEmpty();
    }
     @Override
    public int getCapacity(){
        return array.getCapacity();
    }
     @Override
    public int enqueue(){
        array.addLast(e);
    }
    @Override
    public int dequeue(){
        return array.removeFirst();
    }
    @Override
    public E getFront(){
        return array.getFirst();
    }
    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append("Queue: ");
        res.append("front [");
        for(int i  = 0 ; i < arr.getSize();i++){
            res.append(array.get(i));
            if(i!=array.getSize()-1)
                res.append(", ");
        }
        res.append("] tail");
        return res.toString();
    }
}
image-20230309114026340

循环队列

数组队列的问题

在这里插入图片描述

(tail+1)%c==front 队列满

对于循环我们可以查看自己的钟表就能理解了循环的意思。形成一个环,大小由数组容积决定。

public class LoopQueue<E> implements Queue<E>{
    private E[] data;
    private int front,tail;
    private int size;
    public LoopQueue(int capacity){
        data =(E[]) new Obejct[capacity+1];
        front = 0;
        tail  = 0;
        size = 0;
        
    }
    public LoopQueue(){
        this(10);
    }
    public int getCapacity(){
        return data.length-1;
    }
    @Override
    public boolean isEmpty(){
        return front==tail;
    }
    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append("Queue: size = %d, capacity = %d",size,getCapacity());
        res.append("front [");
        for(int i  = front ; i ! = tail;(i+1)%data.length){
            res.append(array.get(i));
            if((i+1)%data.length!=tail)
                res.append(", ");
        }
        res.append("] tail");
        return res.toString();
    }
}

循环队列的实现

	@Override
	public void enqueue(E e){
        if((tail+1)%data.length==front)resize(getCpacity()*2);
        data[tail] = e;
        tail = (tail+1)%data.length;
        size++;
    }
	@Override
	public E dequeue(){
        if(isEmpty())
            throw new IllegalArgumentException("cannot dequeue from an empty queue");
        E ret = data[front];
        data[front] = null;
        front = (front+1)%data.length;
        size--;
        if(size == getCapacity()/4&&resize(getCapacity()/2!=0)
            resize(getCapacity()/2);
        return ret;
    }
	private void resize(int newCapacity){
        E[] newData =(E[]) new Object[newCapacity+1];
        for(int i = 0; i < size ;i++){
            newData[i] = data[(i+front) % data.length];
            
        }
        data = newData;
        front = 0;
        tail = size;
    }
     @Override
     public E getFront(){
          if(isEmpty())
            throw new IllegalArgumentException("from an empty queue");
         return data[front];
     }
     @Override
     public String toString(){
        StringBuilder res = new StringBuilder();
        res.append("Queue: size = %d, capacity = %d",size,getCapacity());
        res.append("front [");
        for(int i  = front ; i ! = tail;(i+1)%data.length){
            res.append(array.get(i));
            if((i+1)%data.length!=tail)
                res.append(", ");
        }
        res.append("] tail");
        return res.toString();
    }

数组队列和循环队列的比较

栈和队列习题集

使用动态数组实现栈和队列,但是现在如果没有这种结果的话。我们需要用栈,应该著怎么实现呢?

使用队列实现栈

使用栈实现队列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/400765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计UI - Adobe xd对象介绍

矩形工具 新建矩形 操作步骤&#xff1a;选择矩形工具&#xff0c;快捷键R&#xff0c;鼠标在画板上拖出矩形即可。 拖动定界框周围圆形手柄&#xff0c;可快速调整矩形大小&#xff0c;也可以输入宽和高的参数对矩形大小进行改变。 移动矩形 操作步骤&#xff1a;选择选择工具…

AWS-解析mysql binlog同步数据方案

虽然是公有云的鼻祖&#xff0c;AWS在某些产品的实现却太不给力&#xff1b;可能是习惯了阿里云喂到嘴边的感觉&#xff0c;AWS很多方案需要自己折腾&#xff0c;蛋疼&#xff01;比如这里要讲的mysql数据同步方案。阿里云产品DTS&#xff0c;点几下就OK了&#xff0c;AWS&…

06_01_Spark SQL

Spark SQL 课程目标 说出Spark Sql的相关概念说出DataFrame与RDD的联系独立实现Spark Sql对JSON数据的处理独立实现Spark Sql进行数据清洗 1、Spark SQL 概述 Spark SQL概念 Spark SQL is Apache Spark’s module for working with structured data. 它是spark中用于处理结…

百家号如何写文章赚钱,百家号写文章真的赚钱?

随着互联网的快速发展&#xff0c;越来越多的人开始关注到写文章赚钱这个领域。而在众多写作平台中&#xff0c;头条号无疑是最受欢迎的一个。那么&#xff0c;百家号写文章赚钱是真的吗&#xff1f;如何写文章赚钱呢&#xff1f;下面我们就来一一解答。 首先&#xff0c;百家号…

Javascript的ES6 class写法和ES5闭包写法性能对比

看到很多闭包写法的函数, 一直怀疑它对性能是否有影响. 还有就是备受推崇的React Hooks函数式写法中出现大量的闭包和临时函数, 我很担心这样会影响性能. 于是, 做了一个实验来做对比. 这个实验很简单, 用md5计算一百万次. 计算过程将结果再放回参数, 这样避免结果没被引用被…

Git 学习(三)—— 本地仓库 — 远程仓库的操作命令

为了可以让其他用户看到自己的成果&#xff0c;我们可以将自己本地仓库的内容上传到远程仓库&#xff1b;如果我们希望借鉴其他用户的成果&#xff0c;我们可以将远程仓库里的一些内容拉取或者克隆到本地仓库。 这里先暂不考虑 本地到远程 或者 远程到本地 的一些相关操作&…

避坑指南—GPL开源协议

0x00 前言 本文主要目的是为了了解一些基础的GPL注意事项&#xff0c;以及防止被一些一知半解的人蒙骗。本文不做任何内容的依据&#xff0c;仅为个人见解&#xff0c;仅供参考。 一些常见的开源协议 GPLBSDMITMozillaApacheLGPL 0x01 GPL GPL许可协议(GNU General Public …

知识点——域适应、域泛化、在线测试适应区别 DA、DG、TTA区别

文章目录1.Domain Adaptation( DA&#xff1a;域适应 )源域和目标域&#xff1a;DA研究问题&#xff1a;DA目标&#xff1a;DA主要思想&#xff1a;DA三种方法&#xff1a;2.Domain generalization( DG&#xff1a;域泛化 )DG研究问题&#xff1a;DG目标&#xff1a;DA和DG优点…

css——图片缩放,拉伸,变形的解决办法

你的图片即将变得超级丝滑图片为什么会拉伸变形&#xff1f;怎么解决&#xff1f;css的object-fit属性object-fit属性有什么用介绍一下object-position举个小栗子图片为什么会拉伸变形&#xff1f; 前端布局时&#xff0c;图片会出现拉伸、缩放和变形的原因可能有多种: 1.例如图…

2.3操作系统-存储管理:页式存储、逻辑地址、物理地址、物理地址逻辑地址之间的地址关系、页面大小与页内地址长度的关系、缺页中断、内存淘汰规则

2.3操作系统-存储管理&#xff1a;页式存储、逻辑地址、物理地址、物理地址逻辑地址之间的地址关系、页面大小与页内地址长度的关系、缺页中断、内存淘汰规则页式存储逻辑地址、物理地址如何判断物理地址和逻辑地址它们之间的地址关系&#xff1f;页面大小与页内地址长度的关系…

现货交易入门之垂死挣扎

本文讲解的也是挣扎形态&#xff0c;前面以已经讲过一个挣扎形态&#xff0c;但是本文这个形态的名字更让人能耳目一新&#xff0c;因为它叫“垂死挣扎线”&#xff0c;这并不是普通的挣扎线。是“垂死”的&#xff01; “垂死挣扎线”与“顶部挣扎线”很相似&#xff0c;都是出…

JavaApi操作ElasticSearch(强烈推荐)

ElasticSearch 高级 1 javaApi操作es环境搭建 在elasticsearch官网中提供了各种语言的客户端&#xff1a;https://www.elastic.co/guide/en/elasticsearch/client/index.html 而Java的客户端就有两个&#xff1a; 不过Java API这个客户端&#xff08;Transport Client&#…

element-ui日期选择器时间差

关于使用element-ui日期选择器时&#xff0c;发现时间差问题&#xff0c;特此记录下 #主要记录三个问题 日期选择器选择时获取到的格式相差八小时当日期格式为–拼接时&#xff0c;转成时间戳会相差八小时&#xff08;2023-03-09&#xff09;DatePicker设置区域范围和校验&…

TiDB数据库架构概述

文章目录TiDB体系架构TiDB ServerStorage Cluster(存储引擎)PD cluster题目TiDB体系架构 TiDB Server Sql语句最先到达 TiDB Server集群 它是无状态的&#xff0c;数据并不是存储在这里面&#xff0c;当一个会话连接到TiDB Server集群上&#xff0c;sql语句发过来&#xff0c…

大数据自学学习技巧?

经常有人说&#xff1a;先别管大数据是什么&#xff0c;现在理解不了没关系&#xff0c;先开始学&#xff0c;等学着学着就明白了&#xff0c;这种学习路线基本是混合的&#xff0c;很难分清楚自己学了这段怎么用在以后项目中&#xff0c;所以会越学越迷茫&#xff0c;但是等你…

机房漏水设备受损,一招轻松避免

随着科学信息技术的发展和社会经济的快速发展,计算机系统得到了广泛的应用&#xff0c;计算机房设备中使用的设备越来越多。 漏水对机房内精密电子设备容易造成损坏&#xff0c;电器短路等。一旦机房发生漏液&#xff0c;水流到线槽&#xff0c;会导致机房断电&#xff0c;造成…

IPv6公共DNS现在提供加密DNS查询

支持DoT/DoH DoT:dns.ipv6dns.comDoH:https://dns.ipv6dns.com/dns-query为什么需要加密DNS 配置: Windows 10/8/7 1 右键网络进入属性或者右键右下角的Inernet进入网络共享中心,如下图: 2 点击网络和共享中心左侧的"更改适配器设置"链接,如下图: 3 选中正…

一文读懂pinia Vue状态管理

文章目录1.概述&#xff1a;2. 准备工作3.pinia 安装及使用3.1. 安装pinia3.2 store的创建和使用3.3 getters 使用3.4 action 的使用3.5 总结示例代码4.总结1.概述&#xff1a; pinia 类似与vue2 中的vuex &#xff0c;实现跨页面共享状态管理&#xff0c;类似与java 中的sess…

Git设置SSH Key

一、git 配置 &#xff08;1&#xff09;打开 git 命令窗口 &#xff08;2&#xff09;配置用户名&#xff08;填自己的姓名&#xff09; git config --global user.name “xinyu.xia” &#xff08;3&#xff09;配置用户邮箱&#xff08;填自己的邮箱&#xff0…

在SNAP中用sentinel-1数据做DInSAR测量---以门源地震为例

在SNAP中用sentinel-1数据做DInSAR测量---以门源地震为例0 写在前面1 数据下载2 处理步骤2.1 split2.2 apply orbit 导入精密轨道2.3 查看数据的时空基线base line2.4 back-geocoding 配准2.5 Enhanced Spectral Diversity2.6 Deburst2.7 Interogram Formation 生成干涉图2.8 M…