数据结构之栈篇

数据结构之栈篇

Hello,大家好!我是老丑,今天给大家分享的是一种数据结构——栈。

数据结构是什么?

数据结构是计算机存储、组织数据的方式。数据结构是指互相之间存在一种或多种特定关系的数据元素的集合。
——【百度百科】

这样听好像晦涩难懂,那么大白话来了。

数据结构其实就是一个以它所具备的方式存取数据的容器。(这里还不懂,那你过来,我来捶你)

栈是什么?

大家可能会说“你这标题不是写了吗,数据结构之栈篇”,那栈肯定是数据结构啊。

数据结构之栈篇

你们说的对!

栈是那么多数据结构中的一种。也是面试常问的一种,当然面试常问的很多,今天我们只讨论这个迷人的

必要的概念

栈顶栈底入栈(进栈,压栈)、出栈(退栈)、栈顶元素。(先让大家有个初步的印象,后面会具体解释)

栈的定义

栈是一种线性表,限定仅在表的末端进行插入和删除操作的线性表。我们称表的末端称之为栈顶,相反地,我们称表的顶端称之为栈底

栈的一些操作

push:向一个栈加入新元素称之为进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素

pop:从一个栈中删除一个元素称之为出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素(知道指哪一个吗?栈顶的上面是没有元素的,现在应该知道了吧)成为新的栈顶元素。

size:返回目前栈存储的元素容量

peek:返回栈顶元素,但是不会删除栈顶元素

empty:判断栈是否为空,这个空的概念就是不存储元素

栈的特性

根据栈的定义和栈的push和pop操作,其实我们不难发现栈的特性。使用栈存储的元素都是先进后出(FILO,First in Last out),后进先出(LIFO,Last in First out),这两个描述都可。

图解

数据结构之栈篇

怕大家理解概念脑补太累,因此我就画了一个图省得大家累。哎,我太贴心了。

栈的具体实现

很开心,大家能看到这里呀,证明大家还是想学习这篇的知识。

下面我会讲一下Java中栈的具体实现。为什么选择Java,因为老丑爱Java!就像老鼠爱大米一样爱。

在Java中,有一个类叫Stack,也就是栈。我们来看看它的Diagram:

数据结构之栈篇

图中的继承关系一目了然对吧,其实Stack的底层就是使用Vector实现的,Vector是一款线程安全的集合。

Stack类中定义的一些方法

public E push(E item) {}
public synchronized E pop() {}
public synchronized E peek() {}
public boolean empty(){}

在这里,我主要是列举了一些栈的操作方法。

在这里不知道大家是否有注意到我们的push方法empty方法并没有使用synchronized进行修饰,但是其他元素操作方法都使用了synchronized操作,其实也就是意味着Stack是一款线程安全的集合,但是push方法为什么没有采用synchronized进行修饰,我希望大家可以自己阅读源码找到答案。大家也可以阅读Java中的并发会有什么问题呢?如何解决呢?

自实现线程安全Stack

在这里我们采用ArrayList来实现我们的Stack(当然不止一种实现方式),如果对ArrayList不熟悉的小伙伴,可以阅读ArrayList源码解析,里面有分享ArrayList的一些知识。

public class MyStack {

    // 承载元素的容器
    private ArrayList<String> stacks;

    // 栈的大小
    private int size;

    public MyStack() {
        stacks = new ArrayList<>();
        size = 0;
    }

    // push 压栈
    public synchronized String push(String item) {
        stacks.add(item);
        size++;
        return item;
    }

    // 判断栈是否为空
    public synchronized boolean empty() {
        return size == 0;
    }

    // 获取栈的大小
    public synchronized int size() {
        return size;
    }

    // 获取栈顶元素
    public synchronized String peek() {
        if(empty()) {
            return null;
        }
        return stacks.get(size - 1);
    }

    // 出栈
    public synchronized String pop() {
        if(empty()) {
            return null;
        }
        String item = stacks.get(size - 1);
        size--;
        stacks.remove(size);
        return item;
    }

}

小测试

如果大家看到这里,想必大家已经对栈有了一定的认识。

纸上得来终觉浅,绝知此事要躬行!

那么下面我就出一道题来测试测试大家呀,帮大家回顾回顾呢。

问题: 现在有一个栈,我们将ABCDE以A,B,C,D,E的次序放入到栈中,在放入的过程中是允许出栈的,而且最后栈保证是空的(也就是将栈中的元素全部弹出),那么下面哪一个是不可能是出栈顺序。

  1. BCDAE
  2. EDACB
  3. BCADE
  4. AEDCB

想看答案吗?没有。

数据结构之栈篇

答案在本文末尾,就怕大家不小心看到(偷瞄)答案。大家可以花点时间来做下这题,也可以将前面的概念融合进来进行巩固。

终极测试

可是有些小伙伴就是特别优秀,什么都难不住他。

数据结构之栈篇

那么就出道题给大家思考啦。(这道题是LeetCode上面的呢,Easy题)

这题目可以使用栈来解决,大家加油呀。

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true
示例 2:

输入: "()[]{}"
输出: true
示例 3:

输入: "(]"
输出: false
示例 4:

输入: "([)]"
输出: false
示例 5:

输入: "{[]}"
输出: true

来源:力扣(LeetCode)

栈的应用

栈的应用场景很多,很多问题解决方法都会采用栈。其实我们的方法调用其实也是栈哦。

  • 数制转换
  • 括号匹配
  • 逆波兰表达式

以上应用大家想了解的话,可以自行百度或者上掘金等一系列学习平台

最后

推文到这里,就基本结束了。希望小伙伴能从这篇推文中,Get一些知识。

学习路上有FingerDance,不孤单。欢迎加群(不失联)

我是老丑,一位又老又丑的少年!我们下期见。

觉得推文写得还不错的小伙伴,还请点赞、关注、转发支持下。

数据结构之栈篇

小测试答案: 2

往期推荐:

我们是FingerDance,欢迎加入我们!

原文始发于微信公众号(FingerDance):数据结构之栈篇

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/26783.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!