首页 > 其他分享 >栈和队列(上)-栈

栈和队列(上)-栈

时间:2024-10-28 12:19:28浏览次数:8  
标签:出栈 队列 栈顶 元素 usedSize elem int

1. 栈的概念

        引入:

        我们平时拿羽毛球,是从盒子顶部的羽毛球开始拿的,而顶部的元素是我们最后放进去的.

        栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则.总而言之就是一个后进先出的线性表

压栈: 在栈里面插入元素,也叫做进栈/压栈/入栈.入数据是在栈顶

出栈: 在栈里面删除元素,也叫做出栈.出数据在栈顶

 2. 实现栈的方式

        我们实现栈可以用数组来实现,也可以用链表来实现栈.

        从上图中可以看到,Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的.

       我们也可以用链表来实现栈,我们如果用双链表来实现栈就很方便不管在把头当栈顶还是把尾当栈顶,出入栈都是O(1),但是如果用单链表,把它的尾巴当栈顶,那么出入栈就是O(n),用头当栈顶和双链表一样是O(1)

3. 栈的底层实现

        我们为了更好的理解栈,我们来自己实现一个栈

        首先我们写一个IStack接口

        然后我们写一个MyStack类实现这个接口,我们先来解释一下接口的一些变量,我们实现MyStack是使用的数组来实现的,所以我们先定义一个elem数组,我们再创建一个usedSize变量来记录有效数据的个数,然后设置一个默认容量,并且生成俩个构造方法,一个无参数的构造方法,在创建栈的时候默认容量是10,一个有参的构造方法,我们要大就设置多大的值.

        3.1  判断栈是不是满 isFull()

        当usedSize的大小和elem数组的大小一样的时候,我们就知道栈满了,如果不一样则没满.

        3.2 判断栈是不是空的 empty()

        如果usedSize的大小为0,说明栈里面没有元素了.

        3.3 计算栈的有效数据的数目(栈的大小) size()

        我们设置count变量,然后遍历整个栈,进行计数,其实也可以直接返回usedSize.

        3.4 入栈 push(int x)

        我们的usedSize下标就相当于一个下标,表示没有元素在数组里面的下标,因此我们直接借助usedSize即可,也就是elem[usedSize] = x;usedSize++;这就是入栈操作,不过在把元素放进去之前我们要判断栈是不是满了,如果满了我们就要进行二倍扩容也就是

                                   elem =Arrays.copyOf(elem,2*elem.length);

        3.5 出栈  pop()

        我们的出栈,首先要判断栈是不是空,如果式空我们需要抛出异常,在这个基础上,我们进行出栈操作,我们先保存出栈的元素的值,然后操作usedSize下标即可,因为我们入栈也是通过usedSize下标,就算数组下标之前有值,我们也可以直接覆盖掉.

        

        

        3.6 查看栈顶元素 peek()

        我们查看栈顶元素同样要看栈是不是空的,然后我们直接返回usedSize-1下标的elem数组的值即可.

整体代码:

package 栈和队列;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;

public class MyStack implements IStack{
    //我们的栈底层是个数组
    private int[] elem;
    private int usedSize;//有效数据的个数
    private static final int DEFALUT_CAPACITY = 10;
    public MyStack() {
        elem = new int[DEFALUT_CAPACITY];
    }
    public MyStack(int capacity) {
        elem = new int[capacity];
    }
    @Override
    public void push(int x) {
        //TODO 入栈
        //先判断栈是不是满的
        if(isFull()) {
            elem = Arrays.copyOf(elem, 2 * elem.length);
        }
        //把usedSize位置赋值为x
        elem[usedSize] = x;
        usedSize++;
    }

    @Override
    public int pop() {
        //TODO 出栈
        //先判断是不是没有元素
        if(empty()){
            //抛异常
            throw new EmptException("栈空,无法出栈! ");
        }
        //我们的usedSize相当于存储了下标
        int old = elem[usedSize - 1];
        usedSize--;//这个就相当于删除,虽然原来位置还是有值,但是我们后期push会覆盖掉原先的值
        //如果是引用类型: elem[usedSize] = null;
        return old;
    }

    @Override
    public int peek() {
        //TODO 看栈顶元素
        //先判断是不是没有元素
        if(empty()){
            //抛异常
            throw new EmptException("栈空,无法出栈! ");
        }

        return elem[usedSize - 1];//直接返回即可
    }

    @Override
    public int size() {
        int count = 0;
        for (int i = 0; i < usedSize; i++) {
            count++;
        }
        return count;
    }

    @Override
    public boolean empty() {

        return usedSize == 0;
    }

    @Override
    public boolean isFull() {
        if (usedSize == elem.length){
            return true;
        }
        return false;

    }
}

4. java提供的栈的方法的使用和介绍

        下面是栈的方法:

方法功能
Stack()构造一个空的栈
E push(E e)入栈并返回e
E pop()出栈并返回栈顶元素
E peek()获取栈顶元素
int size()获取栈种有效元素的个数
boolean empty()检测栈是否为空

E这里表示泛型,泛型表示引用数据类型.

        我们来使用一下:

public class T1 {
    public static void main(String[] args) {
        Stack<Integer> s = new Stack();
        s.push(1);
        s.push(2);
        s.push(3);
        s.push(4);
        System.out.println(s.size()); // 获取栈中有效元素个数---> 4
        System.out.println(s.peek()); // 获取栈顶元素---> 4
        s.pop(); // 4出栈,栈中剩余1 2 3,栈顶元素为3
        System.out.println(s.pop()); // 3出栈,栈中剩余1 2 栈顶元素为3
        if (s.empty()) {
            System.out.println("栈空");
        } else {
            System.out.println(s.size());
        }
    }
}
结果:
4
4
3
2

5. 栈、虚拟机栈、栈帧的区别

栈: 一种规定只能在一端进行插入或者删除的线性表,是一种后进先出的数据结构.

虚拟机栈: 是Java虚拟机(JVM)的一个概念,每个线程运行的时候都会创建自己的虚拟机栈.

简而言之: JVM划分的一块内存.

栈帧: 是用于支持Java虚拟机进行方法调用和方法执行的数据结构,是虚拟机栈的一部分,每次发生方法的调用就会为该方法创建一个新的栈帧并压入栈顶.

简而言之: 方法调用的时候会在虚拟机给方法开辟一块内存.

标签:出栈,队列,栈顶,元素,usedSize,elem,int
From: https://blog.csdn.net/2201_75880772/article/details/143273798

相关文章

  • Java 中的 队列(Queue)与双端队列(Deque)
    这篇笔记期初是因为在刷算法题的过程中,发现其他解题方法很多地方有采用栈或者队列来解题,我在这方面比较薄弱,特此学习记录一下。关于队列,我的初始印象就是先进先出,但是通过学习,了解到队列还有双端队列(Deque)、优先队列(PriorityQueue)等类型,不同的队列有不同的进出规则。 队列(Qu......
  • 重生之“我打数据结构,真的假的?”--3.栈和队列(无习题)
    栈和队列C语言中的栈和队列总结在C语言中,**栈(Stack)和队列(Queue)**是两种非常重要的数据结构。它们广泛用于各种应用中,比如内存管理、任务调度、表达式求值等。本文将对这两种数据结构进行详细的介绍,并展示如何在C语言中实现它们。1.栈(Stack)栈是一种先进后出(LIFO,LastIn......
  • 栈与队列(概念与实现)
    目录前言一,栈1,栈(Stack)2,栈的实现3,栈的用途二,队列1,队列(Queue)2,队列的实现3,队列的用途4,环形队列5,环形队列的用途前言     栈与队列,作为核心的数据结构,对于每一位程序员来说都至关重要。它们简化了问题解决的过程,提升了代码的效率。    在这篇博客中,......
  • 数据结构之队列
    一、队列的定义队列是一种操作受限的线性表,队列只允许在表的一端进行插入,在表的另一端进行删除。可进行插入的一段称为队尾,可进行删除的一端称为队头。队列的主要特点就是先进先出。依照存储结构可分为:顺序队和链式队。二、顺序队列一开始front(队头)和rear(队尾)都在数......
  • 关于 顺序表、单链表、双链表、栈、队列的小总结
    1.结构的定义方式-顺序表:以结构体指针方式定义-链表:以结构体自引用方式定义-栈:个人推荐使用结构体指针方式定义(类似顺序表)-队列:以结构体指针+结构体自引用方式实现2.对顺序表、单链表、双链表的小小对比顺序表:尾插、尾删操作更方便(对头操作的话需......
  • 延迟队列的安装步骤
    RabbitMQ中的延迟队列(DelayedQueue)是一种特殊的队列,用于在消息被发送后延迟一段时间再投递给消费者。它在许多场景中非常有用,例如需要定时执行的任务、限流、重试机制等。使用场景定时任务:例如发送提醒邮件或通知,确保在特定时间后再执行。限流:控制请求速率,防止瞬时高并......
  • 国产东方通消息队列TongLINKQ8.1服务端安装步骤
    一、服务端安装groupaddtlq# 新建组useradd-m-gtlqtlq# 新建tlq用户并指定组tlqcd/home/tlq/# 切换到安装目录并上传安装包tar-xzvfInstall_TLQ_Standard_Linux2.6.32_x86_64_8.1.16.0.tar.gz#解压安装文件cd/home/tlq/TLQ8/设置环境变量c......
  • 数据结构——队列和栈
    目录一、栈        1、概念与结构    2、栈的结构与初始化    3、入栈        4、出栈         5、取栈顶元素         6、取栈中有效元素个数          7、栈是否为空 二、队列     1、概念......
  • 数据结构 ——— C语言实现链式队列
    目录队列的概念以及示意图数组队列和链式队列链式队列的结构 实现链式队列的准备工作实现链式队列1.初始化2.打印队列的所有数据3.数据入队列(尾插)4.数据出队列(头删)5.访问队头的数据6.访问队尾的数据7.队列数据总个数8.判断队列是否为空9.释放队列的所......
  • C++ 双端队列实现
    #include<iostream>usingnamespacestd;#defineullisize_ttemplate<classT>classDualStack{private: structNode{ Tdata; Node*next; }; Node*head,*tail; Node*p; ullilength;public: DualStack(){ head=NULL; length=0......