您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

一小时搞定关于栈的那点事儿,其实挺简单的

时间:2020-04-27 11:39:39  来源:  作者:

1 后入先出的结构

这是一个后入先出的结构,和先入先出的队列恰好相反,下面我们就介绍一下这个后入先出的结构——栈。

在日常使用栈最明显的地方,绝对就是浏览器了,浏览器的前进后退就是使用了栈,每次浏览的网页全部都加入到栈中,每次后退时,就进行出栈的操作即可。

栈也是一种线性结构,只能在一端进行插入和删除的操作,先进入的元素被压入栈底,后进入的元素在栈顶,栈底的位置是固定不变的。

栈所拥有的具体的方法如下:

boolean isFull() :判断栈是否满

boolean isEmpty() :判断栈是否空

boolean push(int x) :入栈

boolean pop() :出栈

int top():获取栈顶元素

2 图示入栈与出栈

push 入栈图示 :

一小时搞定关于栈的那点事儿,其实挺简单的
 
 
 

pop 出栈图示 :

一小时搞定关于栈的那点事儿,其实挺简单的
 
 
 

出栈和入栈的时间复杂度都是O(1)

3 使用数组实现栈的数据结构

package com.banana.stack;

public class MyStack {

private int size;

private int[] nums;

private int top;

// 构造函数,声明大小

public MyStack(int size) {

this.size = size;

nums = new int[size];

top = -1;

}

// 出栈

public boolean pop() {

if (isFull()) {

return false;

} else {

top--;

return true;

}

}

// 入栈

public boolean push(int x) {

if (isFull()) {

return false;

} else {

nums[++top] = x;

return true;

}

}

// 判空

public boolean isEmpty() {

return top == -1;

}

// 判满

public boolean isFull() {

return top == (size - 1);

}

// 获取栈顶元素

public int top() {

if (isEmpty()) {

return -1;

} else {

return nums[top];

}

}

}

4 计算1-n的和

计算从1到n的和,最简单的办法是可以用公式方法做,直接(1+n)/2就能得到结果,但是我们使用递归的办法,利用栈的数据结构,也能得到我们想要的结果

package com.banana.stack;

public class SumTest {

public static void main(String[] args) {

System.out.println(Sum(5));

}

private static int Sum(int n) {

if (n == 0) return 0;

return n + Sum(n - 1);

}

}

打个断点,我们就可以看到函数的调用关系,可以很清楚的看到利用栈来进行函数调用,计算结果依次return,就能得到最后的值

一小时搞定关于栈的那点事儿,其实挺简单的
 
 
 

函数栈调用关系:

一小时搞定关于栈的那点事儿,其实挺简单的
 
 
 

5 括号匹配

应用leetcode上面的一道题,括号匹配,利用栈就可以很好的运算,题目是这样的:

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

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

使用栈进行匹配,如果遇到左括号就进行入栈操作,如果遇到右括号,那就进行出栈操作和当前的右括号进行匹配,匹配成功就继续,匹配不成功就直接返回

class Solution {

public boolean isValid(String s) {

Stack<Character> stack = new Stack<>();

for (int i = 0; i < s.length(); i++) {

char c = s.charAt(i);

if (c == '(' || c == '[' || c == '{') stack.push(c);

else if (c == ')') {

if (stack.isEmpty() || stack.pop() != '(') return false;

} else if (c == ']') {

if (stack.isEmpty() || stack.pop() != '[') return false;

} else if (c == '}') {

if (stack.isEmpty() || stack.pop() != '{') return false;

}

}

if (!stack.isEmpty()) return false;

return true;

}

}

其实栈会进行如下的操作进行匹配

一小时搞定关于栈的那点事儿,其实挺简单的
 
 
 

6 双栈运算

这部分来自《算法(第四版)》,我觉得实在是相当不错,就放在这里了,算是张涨姿势吧

计算算式 `` 的值,我们使用两个栈来完成这个任务,一个栈用来保存运算符,一个栈用来保存操作数。

表达式由括号、运算符和操作数组成。我们根据以下4种情况从左到右逐个将这些实体送入栈处理:

  • 将操作数压入操作数栈
  • 将运算符压入运算符栈
  • 忽略左括号
  • 在遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈

package com.banana.stack;

import JAVA.util.Stack;

public class Evaluate {

public static void main(String[] args) {

String str = "(1 + ( (2+3) * (4*5) ) )";

System.out.println(calculate(str));

}

public static double calculate(String str) {

Stack<String> ops = new Stack<String>();

Stack<Double> vals = new Stack<Double>();

for (int i = 0; i < str.length(); i++) {

String ele = "" + str.charAt(i);

// Neglect the operator "(" and " "

if (ele.equals("(") || ele.equals(" ")) ;

else if (ele.equals("+")) ops.push(ele);

else if (ele.equals("-")) ops.push(ele);

else if (ele.equals("*")) ops.push(ele);

else if (ele.equals("/")) ops.push(ele);

else if (ele.equals(")")) {

String op = ops.pop();

double v1 = vals.pop();

double v2 = vals.pop();

if (op.equals("+")) vals.push(v1 + v2);

if (op.equals("-")) vals.push(v1 - v2);

if (op.equals("*")) vals.push(v1 * v2);

if (op.equals("/")) vals.push(v1 / v2);

} else vals.push(Double.valueOf(ele));

}

return vals.pop();

}

}

这段Stack的用例使用了两个栈来计算表达式的值。它展示了一种重要的计算模型:将一个字符串解释为一段程序并执行该程序得到结果。有了泛型,我们只需实现Stack一次即可使用String值得栈和Double值得栈。

一小时搞定关于栈的那点事儿,其实挺简单的
 
 
 

7 写在最后

栈使用得场景相比较队列、链表会少一点,但是它的重要性一点不比它们差,所以一定需要认真得思考与总结,学习完只有进行总结,才能把知识变成自己的。



Tags:   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
ROP是一种技巧,我们对execve函数进行拼凑来进行system /bin/sh。栈迁移的特征是溢出0x10个字符,在本次getshell中,还碰到了如何利用printf函数来进行canary的泄露。ROP+栈迁移...【详细内容】
2021-12-15  Tags:   点击:(22)  评论:(0)  加入收藏
IPv6是英文“Internet Protocol Version 6”(互联网协议第6版)的缩写,是互联网工程任务组(IETF)设计的用于替代IPv4的下一代IP协议,其地址数量号称可以为全世界的每一粒沙子编上一...【详细内容】
2021-11-23  Tags:   点击:(35)  评论:(0)  加入收藏
有点眼晕,以下只是我们会用到的一些语言的合集,而且只是语言层面的一部分,就整个后台技术栈来说,这只是一个开始,从语言开始,还有很多很多的内容。今天要说的后台是大后台的概念,放...【详细内容】
2021-09-14  Tags:   点击:(63)  评论:(0)  加入收藏
尚硅谷前端研究院第 1 章:Vue 核心 Vue 简介官网英文官网: https://vuejs.org/中文官网: https://cn.vuejs.org/介绍与描述 动态构建用户界面的渐进式 JavaScript 框...【详细内容】
2021-08-26  Tags:   点击:(115)  评论:(0)  加入收藏
用户通过系统返回按钮导航回去的一组页面,在开发中被称为返回栈 (back stack)。多返回栈即一堆 "返回栈",对多返回栈的支持是在 Navigation 2.4.0-alpha01 和 Fragment 1.4.0...【详细内容】
2021-08-17  Tags:   点击:(76)  评论:(0)  加入收藏
随着介绍的新工具和技术,开发人员技术景观一直变化。通过对职位板上的无数职位描述进行了大量的采访和阅读,我认为这是2021年的JavaScript开发商的伟大现代化技术堆栈。我的...【详细内容】
2021-07-22  Tags:   点击:(165)  评论:(0)  加入收藏
刚入门Web开发者总会听到前端开发、后端开发、全栈开发等岗位描述及相关介绍说明。很多人不清楚前端、后端、全栈到底指的是什么?对应岗位需求是什么?俗话说“磨刀不误砍柴工...【详细内容】
2021-06-16  Tags:   点击:(134)  评论:(0)  加入收藏
UDP报文接收概述UDP数据报的接收要分两部分来看: 网络层接收完数据包后递交给UDP后,UDP的处理过程。该过程UDP需要做的工作就是接收数据包并对其进行校验,校验成功后将其放入接...【详细内容】
2021-06-04  Tags:   点击:(94)  评论:(0)  加入收藏
各位读者朋友们好,我是龙叔,1名退休老码农,如果从工作算起的话我的码龄有18年,今天我来对前端、后端、全栈这3个方面分享一下我的见解,对于准备学编程或者刚学编程不久的小友,让我...【详细内容】
2021-05-19  Tags:   点击:(189)  评论:(0)  加入收藏
相信很多学Java的同学都有想转大数据或者学大数据的想法,但是一看到网上那些大数据的技术栈,就一脸懵逼,什么Hadoop、HDFS、MapReduce、Hive、Kafka、Zookeeper、HBase、Sqoop...【详细内容】
2021-04-20  Tags:   点击:(124)  评论:(0)  加入收藏
▌简易百科推荐
前言Kafka 中有很多延时操作,比如对于耗时的网络请求(比如 Produce 是等待 ISR 副本复制成功)会被封装成 DelayOperation 进行延迟处理操作,防止阻塞 Kafka请求处理线程。Kafka...【详细内容】
2021-12-27  Java技术那些事    Tags:时间轮   点击:(1)  评论:(0)  加入收藏
博雯 发自 凹非寺量子位 报道 | 公众号 QbitAI在炼丹过程中,为了减少训练所需资源,MLer有时会将大型复杂的大模型“蒸馏”为较小的模型,同时还要保证与压缩前相当的结果。这就...【详细内容】
2021-12-24  量子位    Tags:蒸馏法   点击:(11)  评论:(0)  加入收藏
分稀疏重建和稠密重建两类:稀疏重建:使用RGB相机SLAMOrb-slam,Orb-slam2,orb-slam3:工程地址在: http://webdiis.unizar.es/~raulmur/orbslam/ DSO(Direct Sparse Odometry)因为...【详细内容】
2021-12-23  老师明明可以靠颜值    Tags:算法   点击:(7)  评论:(0)  加入收藏
1. 基本概念希尔排序又叫递减增量排序算法,它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的;希尔排序是一种不稳定的排序算法...【详细内容】
2021-12-22  青石野草    Tags:希尔排序   点击:(6)  评论:(0)  加入收藏
ROP是一种技巧,我们对execve函数进行拼凑来进行system /bin/sh。栈迁移的特征是溢出0x10个字符,在本次getshell中,还碰到了如何利用printf函数来进行canary的泄露。ROP+栈迁移...【详细内容】
2021-12-15  星云博创    Tags:栈迁移   点击:(22)  评论:(0)  加入收藏
一、什么是冒泡排序1.1、文字描述冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地...【详细内容】
2021-12-15    晓掌柜丶韶华  Tags:排序算法   点击:(16)  评论:(0)  加入收藏
在了解golang的map之前,我们需要了解哈希这个概念。哈希表,又称散列表(Hash table),是根据键(key)而直接访问在内存储存位置的数据结构。也就是说,它通过计算出一个键值的函数,将...【详细内容】
2021-12-07  一棵梧桐木    Tags:哈希表   点击:(14)  评论:(0)  加入收藏
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯&middot;奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  小心程序猿QAQ    Tags:雪花算法   点击:(24)  评论:(0)  加入收藏
导读:在大数据时代,对复杂数据结构中的各数据项进行有效的排序和查找的能力非常重要,因为很多现代算法都需要用到它。在为数据恰当选择排序和查找策略时,需要根据数据的规模和类型进行判断。尽管不同策略最终得到的结果完...【详细内容】
2021-11-04  华章科技    Tags:排序算法   点击:(40)  评论:(0)  加入收藏
这是我在网上找的资源的一个总结,会先给出一个我看了觉得还行的关于算法的讲解,再配上实现的代码: Original author: Bill_Hoo Original Address: http://blog.sina.com.cn/s/bl...【详细内容】
2021-11-04  有AI野心的电工和码农    Tags: KMP算法   点击:(36)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条