数据结构与算法——14.栈

news2024/11/24 21:08:13

目录

1.概述

2.栈的接口设计

3.用链表来实现栈

4.用数组来实现栈

5.用两个栈来实现一个队列

6.用一个队列来实现一个栈

7.总结

1.概述

计算机科学中,stack是一种线性的数据结构,只能在其一端添加数据和移除数据。习惯来说,这一端称之为栈顶,另一端不能操作数据的称之为栈底,就如同生活中的一摞书。

说明:栈是线性的,只能在一端进行操作,分为栈顶和栈底两部分,包括入栈和出栈操作。

2.栈的接口设计

下面看一下栈的接口设计:

很简单,就是入栈,出栈,判断是否为空等操作。

3.用链表来实现栈

下面看一下如何用链表来实现栈:

代码:



public class L12_LinkedListStack<E> implements L12_Stack<E> {

    /**定义节点类*/
    public  class Node{
        E value;
        Node next;

        public Node() {
        }

        public Node(E value, Node next) {
            this.value = value;
            this.next = next;
        }
    }

    private int capacity;//栈的容量
    private int size;//栈中有效数据个数
    Node head = new Node(null,null);

    /*向栈顶添加元素*/
    @Override
    public boolean push(E value) {
        if(isFUll())
            return false;
        Node node = new Node(value, head.next);
        head.next = node;
        size++;
        return true;
    }

    /*弹出栈顶的元素*/
    @Override
    public E pop() {
        if (isEmpty())
            return null;
        Node p = head.next;
        head.next = p.next;
        size--;
        return p.value;
    }

    /*返回栈顶元素*/
    @Override
    public E peek() {
        if (isEmpty())
            return null;
        return head.next.value;
    }

    @Override
    public boolean isEmpty() {
        return head.next==null;
    }

    @Override
    public boolean isFUll() {
        return size == capacity;
    }
}

说明:总的来说还是很简单的,只要会链表的相关操作,那么就可以轻松实现

4.用数组来实现栈

下面来看一下如何用数组来实现栈:

代码:
 



public class L12_ArrayStack<E> implements L12_Stack<E>{

    private E[] array;
    private int top;//栈顶指针

    public L12_ArrayStack(int capacity) {
        this.array = (E[])new Object[capacity];
    }

    @Override
    public boolean push(E value) {
        if (isFUll())
            return false;
        array[top] = value;
        top++;
        return true;
    }

    @Override
    public E pop() {
        if (isEmpty())
            return null;
        E value = array[--top];
        //top--;
        return value;
    }

    @Override
    public E peek() {
        if (isEmpty())
            return null;
        return array[top-1];
    }

    @Override
    public boolean isEmpty() {
        return top == 0 ;
    }

    @Override
    public boolean isFUll() {
        return top == array.length;
    }
}

说明:用数组实现栈也很简单。其中的关键点就是定义了一个指针top,你可以理解其为指针,也可以理解其为栈中有效元素的个数。这就是数组来实现一些线性数据的好处,数组的元素个数相当于一个指针,一个指针的值也相当于数组中元素的个数。

5.用两个栈来实现一个队列

下面俩看一下如何用两个栈来模拟一个队列:

代码:

public class L13_TwoStackToQueue {

    L12_ArrayStack<Integer> s1 = new L12_ArrayStack(100);//前半个
    L12_ArrayStack<Integer> s2 = new L12_ArrayStack(100);//后半个

    /**入队操作,就是直接在后半个栈中压栈就行*/
    public void push(int x){
        s2.push(x);
    }
    /**出队操作*/
    public int pop(){
        if (s1.isEmpty()){
            while (!s2.isEmpty()){
                s1.push(s2.pop());
            }
        }
        return s1.pop();
    }

    /**返回队首元素*/
    public int peek(){
        if (s1.isEmpty()){
            while (!s2.isEmpty()){
                s1.push(s2.pop());
            }
        }
        return s1.peek();
    }

    public boolean empty(){
        return s1.isEmpty() && s2.isEmpty();
    }
}

说明:

栈只有一端可以操作,是先入后出的,队列是两端都可以操作,是先入先出的。那么肯定要有两个栈,一个做队首,一个做队尾。入队操作就是后面栈的入栈操作。关键在与于出队。我们可以将后面栈的元素依次出栈,然后再将这些元素依次压入到前面的一个栈中,这样就改变了元素的顺序,再使用前面一个栈的出栈操作,就实现了出队操作。判断空就是两个栈都为空时队列才为空。

6.用一个队列来实现一个栈

下面来看一下如何用一个队列来实现一个栈:

代码:


public class L14_QueueToStack {

    L9_ArrayQueue1<Integer> q1 = new L9_ArrayQueue1(100);
    private int size = 0;//记录队列中元素的个数

    public void push(int x){
        q1.offer(x);
        for (int i = 0; i < size; i++) {
            q1.offer(q1.poll());
        }
        size++;
    }

    public int poll(){
        size--;
        return  q1.poll();
    }

    public int pop(){
        return q1.peek();
    }

    public boolean empty(){
        return q1.isEmpty();
    }
}

说明:

首先,我们要明确哪里是栈顶,哪里相当于栈底。结合题目看,队首为栈顶,队尾为栈底。这个实现的关键在与入栈操作。当我们从队尾入队后,前面已经入队的元素就跑到栈顶了,这不符合栈的规则。怎么才能让后入的元素在栈顶即在队首?我们可以将前面已经入队的元素依次弹出,然后再将这些元素依次入队,这样我们新加入的元素就这栈顶了,也就是队首了。然后出栈操作和判断空就很简单了。

7.总结

栈其实也很简单。就是很简单入栈,出栈等操作。栈是单端口操作的数据结构,入栈和出栈都只在一个端口。栈可以用链表和数组来实现。栈的特点就是先入后出。

暂时就这么多吧

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

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

相关文章

主打低功耗物联网国产替代,纵行科技ZT1826芯片以速率和灵敏度出圈

在低功耗物联网领域&#xff0c;国产替代的趋势越演越烈。 9月20日&#xff0c;纵行科技在“IOTE 2023深圳物联网通信技术与应用高峰论坛”发表了“自主原创Advanced M-FSK调制技术助力国产替代和泛在物联”的演讲&#xff0c;并推出了ZT1826芯片&#xff0c;以“更低功耗、更…

【lesson8】操作系统的理解和类比

文章目录 操作系统是什么&#xff1f;为什么要有操作系统&#xff1f;怎么做&#xff1f;学校的例子&#xff08;理解管理&#xff09;银行的例子&#xff08;类比操作系统&#xff09; 操作系统是什么&#xff1f; 操作系统是一款软件&#xff0c;是为了进行软硬件资源管理的…

CentOS下Redis6.x安装教程

Redis安装教程 文章目录 Redis安装教程一、安装包下载地址二、安装2.1上传服务器解压2.2安装编译所需依赖2.3编译安装 三、启动与停止3.1守护进程启动3.2开机自启动 一、安装包下载地址 https://redis.io/download/ 目前最新的版本是7.0以上的版本&#xff0c;本次使用redis6…

python3+selenium自动化测试介绍详解!

自动化测试是什么&#xff1f; 自动化测试简单来说就是借助工具的方式来辅助手动测试的行为就可以看做是自动化测试。 自动化测试工具有哪些&#xff1f; 现在常用的自动化测试工具包括&#xff1a; QTP&#xff1a;主要用于回归测试和测试同一软件的新版本Robot Framework…

vue2 provide/inject watch 监控inject中值变化

在Vue 2.x中&#xff0c;使用inject注入的值默认情况下是不能被watch直接监控到的&#xff0c;因为inject提供的值不是响应式的。这是Vue 2.x的设计&#xff0c;与Vue 3.x中的provide和inject不同&#xff0c;Vue 3.x中的inject提供的值是响应式的&#xff0c;可以直接被watch监…

【Java 基础篇】Java同步代码块解决数据安全

多线程编程是现代应用程序开发中的常见需求&#xff0c;它可以提高程序的性能和响应能力。然而&#xff0c;多线程编程也带来了一个严重的问题&#xff1a;数据安全。在多线程环境下&#xff0c;多个线程同时访问和修改共享的数据可能导致数据不一致或损坏。为了解决这个问题&a…

心理咨询预约微信小程序开发制作步骤

随着互联网的普及和人们对心理健康的重视&#xff0c;越来越多的心理咨询需求在日常生活中涌现。为了满足这一需求&#xff0c;开发一款心理咨询预约微信小程序势在必行。本文将介绍使用乔拓云网这个第三方制作平台来制作这款小程序的具体步骤。 1. 找一个合适的第三方制作平台…

竞赛选题 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

ChatGPT追祖寻宗:GPT-3技术报告要点解读

论文地址&#xff1a;https://arxiv.org/abs/2005.14165 往期相关文章&#xff1a; ChatGPT追祖寻宗&#xff1a;GPT-1论文要点解读_五点钟科技的博客-CSDN博客ChatGPT追祖寻宗&#xff1a;GPT-2论文要点解读_五点钟科技的博客-CSDN博客 本文的标题之所以取名技术报告而不是论文…

【差旅游记】初见乌海湖

哈喽&#xff0c;大家好&#xff0c;我是雷工。 最近在乌海出差&#xff0c;有幸见到了传说中在沙漠中看海的“黄河明珠”——乌海湖。 前段时间一直有点忙&#xff0c;现在有点时间&#xff0c;趁还没忘光&#xff0c;简单整理记录下。 那是在上个月&#xff0c;2023年8月8号…

K8S:Pod容器中的存储方式及PV、PVC

文章目录 Pod容器中的存储方式一&#xff0e;emptyDir存储卷1.emptyDir存储卷概念2.emptyDir存储卷示例 二.hostPath存储卷1.hostPath存储卷概念2.hostPath存储卷示例 三.nfs共享存储卷1.nfs共享存储卷示例 四.PV和PVC1.PV、PVC概念2.PVC 的使用逻辑及数据流向3.storageclass插…

Conditional DETR(ICCV 21)

Conditional DETR&#xff08;ICCV 21&#xff09; Conditional DETR for Fast Training Convergence 加速detr收敛&#xff08;50 epoch收敛&#xff09; DETR收敛慢的原因 DETR训练收敛速度慢&#xff0c;需要500 epochs DETR的Cross Attention高度依赖content embedding…

Go编程规范

文章目录 注释转义符定义变量方法一&#xff1a;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值方法二&#xff1a;根据值自行判定变量类型(类型推导)方法三&#xff1a;省略var, 注意:左侧的变量不应该是已经声明过的&#xff0c;否则会导致编译错误[推荐]全局…

通讯网关软件001——利用CommGate X2Access-U实现OPC UA数据转储Access

本文介绍利用CommGate X2ACCESS-U实现从OPC UA Server读取数据并同步转储至ACCESS数据库。CommGate X2ACCESS-U是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;实现从OPC UA Server实时读取…

经典指标策略回测一览

编辑 经典指标策略回测一览 关键词 A股市场&#xff08;沪深京三市&#xff09; 5000股票20年内日线走势回测&#xff0c;区分除权&#xff0c;前复权&#xff0c;后复权三种模式&#xff1b;由于数据量较大&#xff0c;采用两种方式共享数据&#xff0c;一是 天启网站的数据…

Minor GC、Young GC、Full GC、Old GC、Major GC、Mixed GC 一文搞懂

简介 大家经常会看到各种各样的 GC 名称&#xff0c;比如&#xff1a;Minor GC、Young GC、Full GC、Old GC、Major GC、Mixed GC。 刚开始看到这么多 GC 名词后&#xff0c;真的是心累 哎&#xff0c;没办法&#xff0c;一声国粹之后也只能慢慢的把它们理理顺。 GC分类 我…

(vue2)面经基础版-案例效果分析

配路由 先配一级&#xff0c;一级里面配二级。一级路由&#xff1a;首页&#xff08;二级&#xff1a;嵌套4个小页面&#xff09;、详情页 高亮a->router-link&#xff0c;高亮效果对自带高亮类名router-link(-exact)-active设置 注&#xff1a;通过children配置项&#…

【springboot源码】深度解析@Value赋值时机及底层原理

1.Value使用 Value主要是让我们程序动态的将外部值注入到bean中的&#xff0c;使用方式主要如下两种&#xff1a; 1.1Value("${}")&#xff1a;可以获取对应属性文件中定义的属性值。 1.2Value("#{}")&#xff1a;表示 SpEl 表达式通常用来获取 bean 的…

【操作系统】聊聊什么是CPU上下文切换

对于linux来说&#xff0c;本身就是一个多任务运行的操作系统&#xff0c;运行远大于CPU核心数的程序&#xff0c;从用户视角来看是并发执行&#xff0c;而在CPU视角看其实是将不同的CPU时间片进行分割&#xff0c;每个程序执行一下&#xff0c;就切换到别的程序执行。那么这个…

[激光原理与应用-70]:AD8512运算放大器的工作原理与连接电路

目录 概述&#xff1a; 一、AD8512的功能与主要特征 一、AD8510 1.1 管脚说明 1.2 电源电压 1.3 输入信号电压 1.4 偏置电压 1.5 参考连接 1.6 放大倍数 1.7 参考电路 二、AD8512 1.1 管脚说明 1.2 AD8512的电路连接 1.3 如何调整放大倍数 1.4 AD8512半波与全波…