栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Stack与栈(Java语言)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Stack与栈(Java语言)

Stack与栈(Java语言)

前言前景介绍

什么是栈?什么是Java虚拟机栈?什么是栈帧? Java内置栈

栈对象栈方法

push()方法pop()方法peek()方法empty()方法search()方法 实现栈

成员变量和构造方法push()方法pop()方法peek()方法search()方法

前言

通过前面的对于ArrayList的学习,我们知道了ArrayList底层就是一个数组,而数组存储数据,我们也可以换一种说法,叫做顺序表。而这篇博客我们就可以系统的介绍一下Stack,也就是栈这种数据结构。

前景介绍

在介绍Stack之前,我们先引入几个问题:

什么是栈?

简而言之,栈是一种数据结构,它的特点就是:先进后出。

举个例子:假如有一组数据12,23,34,45。
我们将数据放入栈中。

可以看到我们是按照12,23,34,45的顺序放入栈中的,那么拿出数据时,就需要先拿出45,34,23,最后拿出12这个数据,所以说叫做先进后出。

什么是Java虚拟机栈?

我们知道JVM内存结构分为五部分:Java虚拟机栈,本地方法栈,堆,方法区,程序计数器。所以我们可以说Java虚拟机栈是JVM当中的一块内存,该内存一般用来存放局部变量等,既然是栈,那么同样它具有栈的特点:先进后出。

什么是栈帧?

这边先挖一个坑,关于栈帧,我们会专门写一篇博客介绍栈帧,我们需要简单知道,当调用函数的时候,我们会专门为这个函数调用开辟一块内存,叫做栈帧。当一个函数结束,那么该函数的内存释放。

Java内置栈

对于Java而言,它是有内置的栈直接供我们使用的。也就是Stack类。

栈对象

跟ArrayList一样,通过new创建对象。

public static void main(String[] args) {
        Stack stack = new Stack<>();
    }
栈方法

对于栈本身而言,栈自己有push()方法,pop()方法,peek()方法,empty()方法,search()方法。

push()方法

形式:public E push(E item)
解释:在栈的最顶部放入一个元素item。
例子:

public static void main(String[] args) {
        Stack stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
    }

这时栈中依次放入1,2,3,4。

pop()方法

形式:public synchronized E pop()
解释:移除栈顶的元素,并返回该元素。
例子:

public static void main(String[] args) {
        Stack stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        System.out.println(stack.pop());//弹出栈顶元素,并且删除 4
    }

结果:

peek()方法

形式:public synchronized E peek()
解释:返回栈顶元素,但并不删除。
例子:

public static void main(String[] args) {
        Stack stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        System.out.println(stack.pop());//弹出栈顶元素,并且删除 4
        System.out.println(stack.peek());//获取栈顶元素,但不删除 3
        System.out.println(stack.peek());//获取栈顶元素,但不删除 3
    }

结果:

empty()方法

形式:public boolean empty()
解释:判断栈是否为null
例子:

public static void main(String[] args) {
        Stack stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        System.out.println(stack.pop());//弹出栈顶元素,并且删除 4
        System.out.println(stack.peek());//获取栈顶元素,但不删除 3
        System.out.println(stack.peek());//获取栈顶元素,但不删除 3
        System.out.println(stack.empty());//栈中还有1,2,3
    }

结果:

search()方法

形式:public synchronized int search(Object o)
解释:如果栈中存在o这个元素,那么返回该元素离栈顶的距离,如果不存在则返回-1。
例子:

public static void main(String[] args) {
        Stack stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        System.out.println(stack.pop());//弹出栈顶元素,并且删除 4
        System.out.println(stack.peek());//获取栈顶元素,但不删除 3
        System.out.println(stack.peek());//获取栈顶元素,但不删除 3
        System.out.println(stack.empty());
        System.out.println(stack.search(3));
    }

结果:

实现栈

为了能够更好的学习栈,我们通过代码自己实现栈。

成员变量和构造方法
public class MyStack {
    public int[] elem;
    public int usedSize;

    public MyStack() {
        this.elem = new int[5];
    }
}

对于栈来说,底层可以用一个数组实现,因此我们需要一个数组存储元素,同样需要一个usedSize作为计数。构造方法只需要实例化一个5个元素的数组,如果不够扩容即可。

push()方法
public boolean isFull() {
        return this.usedSize == this.elem.length;
    }

public void push(int val) {
    if (isFull()) {
        //扩容
        this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
    }
    this.elem[this.usedSize] = val;
    this.usedSize++;
}

在增加元素进入栈时,需要判断栈是否为满,如果为满,那么按照两倍进行扩容,如果没有满,那么在usedSize的位置放入val的值,并且usedSize++。

pop()方法
public boolean isEmpty() {
        return this.usedSize == 0;
    }

public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈为空!");
        }
        int oldVal = this.elem[usedSize - 1];
        this.usedSize--;
        return oldVal;
    }

首先判断栈是否为null,如果栈为null,则无法弹出栈顶元素,因此抛出异常,否则,将数组中usedSize-1的位置的元素返回,并且usedSize–。

peek()方法
public int peek() {
        if (isEmpty()) {
            throw new RuntimeException("栈为空!");
        }
        return elem[usedSize - 1];
    }

与pop()方法类似,只是不需要usedSize-1即可。

search()方法
public int search(int val) {
        int count = usedSize - 1;
        while (elem[count] != val) {
            count--;
            if (count<0){
                return -1;
            }
        }
        return usedSize-count;
    }

将usedSize-1的值赋值给count,当count下标对应的元素不与val值相等,那么count–,直到相等或者count<0,如果相等,返回usedSize与count的差值,如果count<0返回-1。
关于栈我们就介绍到这里,栈的使用核心就是了解到它是先进后出的特点就行了,当然想要更快的掌握栈离不开刷题,如果有什么问题,或者建议,欢迎私信或者评论。谢谢各位!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/710450.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号