数据结构与算法—数组栈和链表栈

news2024/9/21 14:46:50

数据结构与算法—数组栈和链表栈

🌈一览众山小

  • 数据结构与算法—数组栈和链表栈
    • 栈介绍
    • 栈图解
    • 栈实现
      • 数组实现栈
        • 实现思路
        • 实现代码
      • 单链表实现栈
        • 实现思路(图解)
        • 实现代码
    • 栈总结
    • 栈力扣

栈介绍

在这里插入图片描述

  • 栈,存储货物或供旅客住宿的地方,可引申为仓库、中转站,所以引入到计算机领域里,就是指数据暂时存储的地方,所以才有进栈出栈的说法。

  • 栈是一种受限线性表,也就是说,栈元素具有线性关系,即前驱后继关系;只不过它是 一种特殊的线性表而已;

  • 线性表是在表尾进行插入和删除操作,而在栈中表尾是指栈顶,而不是栈底;栈的数据操作始终只在栈顶进行,即先进后出,后进先出;

栈图解

现有五个元素要进入栈中分别:1、2、3、4、5。注:元素进入栈称为"压栈"

在这里插入图片描述

进入后发现先进入的到了最下面,离出口最远。而最后进入的却在最上面,离出口最近

在这里插入图片描述

现需要对栈中数据进行取出,看看情况会是什么样。 注:栈取出元素称为" 弹栈"

在这里插入图片描述

可以发现最先出来的是(5),也就是最后进入的元素。以此类推,最后出来的则是(1)最先进入的元素。

这时候,我们就会发现,栈有 **“先进后出,后进先出”**这个特点。

栈实现

数组实现栈

实现思路

  • 用一个数组实现栈是很简单的。每一个栈都有一个top,对于空栈它是-1(这是空栈的初始化)

  • 为了将某个元素X压入该栈,我们将top加1,然后置stack[top] =X,其stack是代表具体的栈的数据

  • 为了弹出栈元素,我们置返回值为stack[top] ,然后 top减1

实现代码

数组栈 压栈:push()、弹栈:pop()、判满:isFull()、判空:isEmpty()、遍历:list()等方法

ArrayStack.java

class ArrayStack{
    //最大容量
    private int maxSize;
    //栈数据组
    private int[] stack;
    //栈顶
    private int top = -1;
	//构造器设置最大容量
    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[maxSize];
    }

    //栈满
    public boolean isFull(){
        //如果top等于最大为栈满
        return top == maxSize - 1;
    }

    //栈空
    public boolean isEmpty(){
        //如果top等于-1 则为栈空
        return  top == -1;
    }

    //添加栈
    public void  push(int value){
        //如果栈满则不添加
        if (isFull()){
            System.out.println("栈满!!!");
            return;
        }
        //如果没有满则进行栈添加
        top++;
        stack[top] = value;
    }
    //取栈值
    public int pop(){
        //判断栈是否为空
        if (isEmpty()){
            throw new RuntimeException("栈空!!!");
        }
        int value = stack[top];
        top--;
        return value;
    }
    //遍历栈
    public void  list(){
        //从头到尾
        if (isEmpty()){
            System.out.println("栈空!!!");
        }
        for (int i = top; i >=0 ; i--) {
            System.out.printf("栈号为%d 值为 %d\n",i,stack[i]);
        }
    }
}

主程序(测试)


public class ArrayStackDemo {
    public static void main(String[] args) {
        ArrayStack stack = new ArrayStack(5);
        System.out.println("进行压栈~~");
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);
        System.out.println("进行栈遍历~~");
        stack.list();
        System.out.println("进行弹栈~~");
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
	}
}
/* 结果
	进行压栈~~
	进行栈遍历~~
	栈号为4 值为 5
	栈号为3 值为 4
	栈号为2 值为 3
	栈号为1 值为 2
	栈号为0 值为 1
	进行弹栈~~
	5
	4
	3
	2
	1
*/

单链表实现栈

实现思路(图解)

在这里插入图片描述

实现代码

链表节点类

Node.java

/**
 * 链表节点
 */
class Node{
    //链表值
    private int no;
    //单向链表
    private Node next;
    //构造器
    public Node(int no) {
        this.no = no;
    }
    //get set方法
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next = next;
    }
}

链表栈实现类

LinkedStack.java


class LinkedStack{
    //头节点
    private Node head = new Node(-1);
    //栈顶 初始化为-1
    private int top =-1;
    //栈最大容量
    private int maxSize;
    //构造器获取最大容量
    public LinkedStack(int maxSize) {
        this.maxSize = maxSize;
    }

    //判断栈是否满
    public boolean isFull(){
        return top == maxSize -1;
    }
    //判断栈是否为空
    public boolean isEmpty(){
        return top == -1;
    }

    //进行栈添加
    public void push(Node node){
        //先判断栈是否满
        if (isFull()){
            System.out.println("栈满!!!");
        }
        //第一次进行添加特殊,如果top == -1 说明第一次添加
        if (top == -1){
            head.setNext(node);
            top++;
            return;
        }
        //如果不是第一次添加则进行添加逻辑
        Node temp = head;
        //将其他节点后移
        node.setNext(temp.getNext());
        //再将插入值连接到头节点
        temp.setNext(node);
        //栈顶++
        top++;
    }

    //进行取栈值
    public Node pop(){
        //先判断是否为空栈
        if (isEmpty()){
            throw new RuntimeException("栈为空!!!");
        }
        //如果不为空则进行取栈
        Node temp = head;
        Node value = temp.getNext();
        //将节点删除
        temp.setNext(value.getNext());
        top--;
        return value;
    }

    //进行栈遍历
    public void list(){
        //判断是否为空栈
        if (isEmpty()){
            System.out.println("栈为空!!!");
        }
        Node temp = head;
        //进行栈遍历
        for (int i = 0; i <= top; i++) {
            System.out.printf("栈值为:%d\n",temp.getNext().getNo());
            //临时指针进行后移
            temp = temp.getNext();
        }
    }
}

主程序(测试)

public class LinkedStackDemo {
    public static void main(String[] args) {
        Node node1 = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        Node node4 = new Node(4);
        Node node5 = new Node(5);
        LinkedStack linkedStack = new LinkedStack(5);
        System.out.println("链表栈进行添加!!!");
        linkedStack.push(node1);
        linkedStack.push(node2);
        linkedStack.push(node3);
        linkedStack.push(node4);
        linkedStack.push(node5);
        System.out.println("链表栈遍历!!!");
        linkedStack.list();
        System.out.println("链表栈取出!!!");
        System.out.println(linkedStack.pop().getNo());
        System.out.println(linkedStack.pop().getNo());
        System.out.println(linkedStack.pop().getNo());
        System.out.println(linkedStack.pop().getNo());
        System.out.println(linkedStack.pop().getNo());
        System.out.println("取完以后查看链表情况!!!");
        linkedStack.push(node1);
        linkedStack.push(node2);
        linkedStack.pop();
        linkedStack.list();
    }
}
/* 结果
    链表栈进行添加!!!
    链表栈遍历!!!
    栈值为:5
    栈值为:4
    栈值为:3
    栈值为:2
    栈值为:1
    链表栈取出!!!
    5
    4
    3
    2
    1
    取完以后查看链表情况!!!
    栈值为:1
*/

栈总结

前面我们说过,栈是一个线性表。所以,任何实现表的方法都可以用来实现栈

记住本文章的几个关键字:,“先进后出,后进先出”,压栈弹栈栈顶栈底,你已经对栈有基本的了解了。

栈力扣

🌈以后关于栈的力扣题就关联在这下面把

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

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

相关文章

Java—泛型、内部类、多继承

文章目录泛型1.泛型是什么&#xff0c;使用泛型的好处2.泛型中的限定通配符和非限定通配符3.泛型擦除内部类多继承多继承使用&#xff1a;———————————————————————————泛型 1.泛型是什么&#xff0c;使用泛型的好处 ​ 泛型就是把类型参数化&…

骰子游戏-第11届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第94讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…

Python源码剖析1-整数对象PyIntObject

1、PyIntObject 对象 [intobject.h] typedef struct {PyObject_HEADlong ob_ival; } PyIntObjectPyIntObject是一个不可变&#xff08;immutable&#xff09;对象。Python内部也大量的使用整数对象&#xff0c;我们在自己的代码中也会有大量的创建销毁整型对象的操作&#xff…

霍夫曼树:霍夫曼编码(Huffman Tree:Huffman Coding)

预计阅读时间&#xff1a;10分钟 一、简介 霍夫曼树常处理符号编写工作。根据整组数据中符号出现的频率高低&#xff0c;决定如何给符号编码。如果符号出现的频率越高&#xff0c;则给符号的码越短&#xff0c;相反符号的号码越长。 相关术语 路径&#xff1a;从书中一个节点…

Docker安装可视化管理器Portainer

Docker安装可视化管理器Portainer Portainer 提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作&#xff08;包括上传下载镜像&#xff0c;创建容器等操作&#xff09;、事件日志显示、容器控制台操作、Swarm 集群和服务等集中管理和操作、登录用户管理和控制…

Linux/Windows Redis的下载与安装

Redis简介 参考视频教程: https://www.bilibili.com/video/BV13a411q753?p143 Redis下载与安装 Windows版 下载地址: https://github.com/microsoftarchive/redis/releases Linux版下载地址: https://download.redis.io/releases/ 1. Window版本 1.1 redis下载 官网下载…

用ACL实现防火墙功能

目录 实验目的&#xff1a; 实验所需软硬件 实验步骤&#xff1a; 1、按以下拓扑接好线路。 2、配置好设备的IP地址和静态路由&#xff0c;使得所有设备可以互通。&#xff08;配置截图&#xff09; PC2 PC0 Router0 Router1​编辑 Server 3、测试各PC/服务器互联状…

基于KubeSphere图形编辑面板构建微服务项目的DevOps 系统

文章目录相关文章部署过程准备工作创建 DevOps 项目创建凭证创建流水线编辑流水线JAVA后端微服务拉取源码构建源码构建镜像推送镜像部署项目VUE前端拉取源码构建源码构建镜像推送镜像部署项目运行流水线查看流水线详情完整流水线脚本微服务后端VUE前端参考相关文章 kubernetes…

Grafana+Prometheus打造运维监控系统(一)-安装篇

1. Prometheus、Grafana介绍 Prometheus是一个开源的系统监控和报警系统&#xff0c;Grafana 是一个开源的监控数据分析和可视化套件&#xff0c;利用GrafanaPrometheus组合&#xff0c;打造运维日常的各种指标监控以及数据可视化。 2. Prometheus 2.1 下载 访问&#xff1…

专利-分析方法总结

目录 一、专利分析的意义 二、专利分析的方法&#xff1a; 2.1、行业专利信息分析 2.1.1、专利技术发展趋势分析 2.1.2、专利区域分布分析 2.1.3、专利相关人分析 2.1.4、专利技术主题分析 2.1.5、技术发展路线分析 2.1.6、专利技术功效分析 2.1.7、专利运营分析 3.…

node环境的搭建

一、node的安装&#xff08;可以去文末直接安装nvm管理器&#xff0c;就不用配置了&#xff09; 1 下载 | Node.js,也可以下载以往版本,window是以msi结尾的文件 2 安装,直接一直安装就行,如果有之前安装的版本,先进行卸载,然后再进行安装 3 安装完成后查看版本号 node -vnp…

Linux下文件目录权限管理chmod, chown, chgrp,umask命令使用总结

在Linux系统下常用的文件目录权限管理命令有chmod, chown, chgrp,umask&#xff0c;一直以来都在用&#xff0c;但是没有太注意它们的区别&#xff0c;今天就在这篇文章做个总结。 目录 1. chmod 2. chown 3. chgrp 4. umask 1. chmod 作用&#xff1a;修改某个目录或文件…

C语言实现学生管理系统(顺序表版)

前言 设计知识 使用语言&#xff1a;C语言 数据结构类型&#xff1a;顺序表 内容导图 效果展示 内容目录前言设计知识内容导图效果展示静态管理系统菜单的实现选择功能实现静态开辟空间实现增删功能增加功能实现删除功能实现实现查找功能实现修改功能实现排序功能动态管理系…

rollup打包工具快速入门

0.开始 教学视频出处 https://www.bilibili.com/video/BV1w84y1z77V?p3&spm_id_frompageDriver&vd_source0f7f337dd5a99bb975b88a48ae1b3711 日期&#xff1a;2022/12/3 rollup目前版本&#xff1a; "rollup": "^3.5.1"1.rollup概述 官网 http…

N32G45之串口+DMA数据收发

N32G45之串口DMA数据收发 1.串口简介   通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。 USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信&#xff0c;也支持LI…

【云原生】nacos权限制认证

鉴权 服务端如何开启鉴权 非Docker环境 按照官方文档配置启动,默认是不需要登录的&#xff0c;这样会导致配置中心对外直接暴露。而启用鉴权之后&#xff0c;需要在使用用户名和密码登录之后&#xff0c;才能正常使用nacos。 开启鉴权之前&#xff0c;application.properti…

0115 查找算法Day4

剑指 Offer 03. 数组中重复的数字 在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 1&#xff1a; …

Linux-CPU之平均负载

一般我们觉得系统变慢了&#xff0c;都会执行 top 或者 uptime 命令&#xff0c;来了解系统的负载情况。 uptime11:29:06 up 0 min, 2 users, load average: 1.21, 0.29, 0.10// 当前时间 // 系统运行时间 // 正在登录用户数 //1 分钟、5 分钟、15 分钟的平均负载概念&…

补知识点:Stream API

一、创建Stream 首先创建Stream的话&#xff0c;有四种创建方式&#xff1a; 注&#xff1a; 第一种集合的方式是最常用的 package com.atguigu.gulimall.gateway;import com.atguigu.gulimall.streamapi.Employee; import com.atguigu.gulimall.streamapi.EmployeeData; impo…

【应用】Docker

DockerDocker 的安装基本安装流程配置镜像加速Docker 常用命令镜像相关命令容器相关命令DockerfileDockerfile 常用指令Dockerfile 简单使用案例Dockerfile 构建 java 项目镜像Docker ComposeDocker compose 基本参数services 配置参数Docker 的安装 基本安装流程 使用虚拟机…