目录

  • 什么是栈
  • 设计与介绍
    • 数组实现
      • 结构设计
      • push插入
      • pop弹出并返回首位
      • 其他操作
    • 链表实现
      • 结构设计
      • push插入
      • pop弹出
      • 其他操作
  • 实现代码
    • 数组实现
    • 链表实现
    • 测试
  • 总结

什么是栈


百度百科上,栈是这么定义的:

  • 栈(stack)又名堆栈,它是一种运算受限线性表。限定仅在表尾进行插入删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

稍微介绍一下关键名词:

  • 运算受限:也就是这个表你不能随便的删除插入。只能按照它的规则进行插入删除。比如栈就只能在一端就行插入和删除。同样,队列也是运算受限,只能在两天操作。
  • 线性表:栈也是一种线性表,前面详细介绍过线性表,它表达的是一种数据的逻辑关系。也就是在栈内各个元素是相邻的。当然在具体实现上也分数组和链表实现,他们的物理存储结构不同。但是逻辑结构(实现的目的)相同。
  • 栈顶栈底: 这个描述是偏向于逻辑上的内容,因为大家知道数组在末尾插入删除更容易,而单链表通常在头插入删除更容易。所以数组可以用末尾做栈顶,而链表可以头做栈顶。

栈的应用:

  • 栈的应用广泛,比如你的程序执行查看调用堆栈、加减运算、甚至在搜索算法中dfs,替代递归等等。所以栈也是必须掌握的一门数据结构。很多规范也是栈,比如上图放书拿书一样!

设计与介绍

这里我们介绍数组实现的栈和链表实现的栈。

数组实现

结构设计

  • 对于数组来说,我们模拟栈的过程很简单,因为栈是后进先出,我们很容易在数组的末尾进行插入和删除。所以我们选定末尾为栈顶。所以对于一个栈所需要的基础元素是 一个data数组和一个top(int)表示栈顶位置。
  • 那么初始话以及构造的函数代码为:
private T data[];
private int top;
public seqStack() {data=(T[]) new Object[10];top=-1;
}
public seqStack(int maxsize)
{data=(T[]) new Object[maxsize];top=-1;
}

push插入

栈的核心操作之一push:入栈操作。

  • 如果top<数组长度-1。入栈。top++;a[top]=value;
  • 如果top==数组长度-1;栈满。

pop弹出并返回首位

  • 如果top>=0,栈不为空,可以弹出。return data[top--];
  • 如下图,本来栈为1,2,3,4(栈顶),执行pop操作。top变为3的位置并且返回4;

其他操作

  • 其他例如peek操作时返回栈顶不弹出.所以只需满足题意时候return data[top]即可。

链表实现

有数组实现,链表当然也能实现。对于栈的运算。大致可以分为两种思路:

  • 像数组那样在尾部插入删除。大家都知道链表效率低在查询。而查询到尾部效率很低。而我们就算用了尾指针,可以解决尾部插入效率。但是依然无法解决删除效率(删除需要找到前节点).还需要双向链表。前面虽然详细介绍过双向链表,但是这样未免太复杂
  • 所以我们采用带头节点的单链表在头部插入删除,把头部当中栈顶,这样精了很多。插入直接在头节点后插入。而删除也直接删除头节点后第一个元素即可。

结构设计

长话短说,短话不说。直接上代码就懂。
链表的节点

static class node<T>
{T data;node next;public node() {    }public node(T value){this.data=value;}
}

基本结构:

public class lisStack <T>{int length;node<T> head;//头节点public lisStack() {head=new node<>();length=0;}//其他方法
}

push插入

与单链表头插入一致,如果不太了解请先看笔者队线性表介绍的。

和数组形成的栈有个区别。就是理论上栈没有大小限制(不突破内存系统限制)。不需要考虑是否越界。

  • 节点team入栈
  • 空链表入栈head.next=team;
  • 非空入栈team.next=head.next;head.next=team;

pop弹出

与单链表头删除一致,如果不太了解请先看笔者队线性表介绍的。

和数组同样需要判断是否为空。

  • 节点team出栈
  • head指向team后驱节点。不需要考虑链表是否为1个节点。如果为1个节点,team.next=null.执行完毕head.next=null。变为空,满足条件。

其他操作

  • 其他例如peek操作时返回栈顶不弹出.所以只需判空满足题意时候return head.next.data即可。而length你可以遍历链表返回长度,也可以动态设置(本文采取)跟随栈长变化。其他操作直接看api。

实现代码

数组实现

package 队栈;public class seqStack<T> {private T data[];private int top;public seqStack() {data=(T[]) new Object[10];top=-1;}public seqStack(int maxsize){data=(T[]) new Object[maxsize];top=-1;}boolean isEmpty(){return top==-1;}int length(){return top+1;}boolean push(T value) throws Exception//压入栈{if(top+1>data.length-1){throw new Exception("栈已满");}else {data[++top]=value;return true;}}T peek() throws Exception//返回栈顶元素不移除{if(!isEmpty()){return data[top];}else {throw new Exception("栈为空");}}T pop() throws Exception{if(isEmpty()){throw new Exception("栈为空");}else {return data[top--];}}public String toString(){if(top==-1){return "";}else {String va="";for(int i=top;i>=0;i--){va+=data[i]+"  ";}return va;}}
}

链表实现

package 队栈;public class lisStack <T>{static class node<T>{T data;node next;public node() {    }public node(T value){this.data=value;}}int length;node<T> head;//头节点public lisStack() {head=new node<>();length=0;}boolean isEmpty(){return head.next==null;}int length(){return length;}public void push(T value) {//近栈node<T> team=new node<T>(value);if(length==0){head.next=team;}else {team.next=head.next;head.next=team;}length++;}public T peek() throws Exception {if(length==0) {throw new Exception("链表为空");}else {//删除return (T) head.next.data;}}public T pop() throws Exception {//出栈if(length==0) {throw new Exception("链表为空");}else {//删除T value=(T) head.next.data;head.next=head.next.next;//va.nextlength--;return value;}}public String toString(){if(length==0) {return "";}else {String va="";node team=head.next;while(team!=null){va+=team.data+" ";team=team.next;}return va;}}
}

测试

总结

  • 栈的逻辑比较简单。很容易理解,实现起来也相对容易。但是要注意数组情况的界限问题。
  • 后面将介绍队列,相比栈,队列内容更丰富一些。难度也稍大一些。
  • 如果有不好需要改进还请指出
  • 最后,喜欢的话可以关注公众号:bigsai 持续分享(回复 数据结构 获得精心准备资料一份!)

数据结构与算法—栈详解相关推荐

  1. JavaScript数据结构与算法——栈详解

    1.栈基本知识 栈是一种特殊的列表,栈的元素只能通过列表的一端访问,这一端成为栈顶,栈具有先进后出的特点,要想访问栈底的元素,就必须将上边的元素先拿出来.对栈的操作主要是入栈和出栈,通过push()和 ...

  2. c++数据结构中 顺序队列的队首队尾_数据结构与算法—队列详解

    前言 栈和队列是一对好兄弟,前面我们介绍过数据结构与算法-栈详解,那么栈的机制相对简单,后入先出,就像进入一个狭小的山洞,山洞只有一个出口,只能后进先出(在外面的先出去).而队列就好比是一个隧道,后面 ...

  3. 【数据结构与算法】详解什么是图结构,并用代码手动实现一个图结构

    本系列文章[数据结构与算法]所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplo ...

  4. JavaScript数据结构与算法——链表详解(下)

    在JavaScript数据结构与算法--链表详解(上)中,我们探讨了一下链表的定义.实现原理以及单链表的实现.接下来我们进一步了解一下链表的其他内容. 1.双向链表 双向链表实现原理图: 与单向链表不 ...

  5. JavaScript数据结构与算法——链表详解(上)

    注:与之前JavaScript数据结构与算法系列博客不同的是,从这篇开始,此系列博客采用es6语法编写,这样在学数据结构的同时还能对ECMAScript6有进一步的认识,如需先了解es6语法请浏览ht ...

  6. JavaScript数据结构与算法——队列详解(下)

    接下来会借助本人另一篇文章JavaScript数据结构与算法--队列详解(上)中实现的队列类及其方法实现一个应用. 配对问题 需求分析:在一个文件中保存着一份男女混合的数据,名称前以B开头表示男士,以 ...

  7. JavaScript数据结构与算法——列表详解(下),基于Nodejs实现一个列表应用

    1.上篇回顾: 上篇我们实现了一个列表类,并添加了一些属性,实现了比较多的方法,本文章将与大家一起使用列表实现一个图书借阅查询系统.需要使用JavaScript数据结构与算法--列表详解(上)中写好的 ...

  8. JavaScript数据结构与算法——列表详解(上)

    列表是一组有序的数据,每个数组中的数据项称为元素.数组相关知识不够了解的伙伴可以阅读本人上篇博客在JavaScript中,列表的元素可以是任意数据类型.列表中可以保存不定数量的元素,实际使用时元素的数 ...

  9. JavaScript数据结构与算法——数组详解(下)

    1.二维与多维数组 JavaScript只支持一维数组,但是通过在数组里保存数组元素的方式,可以轻松创建多维数组. 1.1 创建二维数组 二维数组类似一种由行和列构成的数组表格,在JavaScript ...

最新文章

  1. python入门到实践-一本书搞定Python入门到实践
  2. C#中的var和dynamic
  3. geth测试私链挖矿时发现很很慢,提高速度
  4. android自定义组件属性,android自定义控件并添加属性的方法以及示例
  5. DI 之 3.4 Bean的作用域(捌)
  6. 阅读react-redux源码(六) - selectorFactory处理store更新
  7. html5如何新建定义站点,HTML5技术教程:创建新作品_HTML5教程_创建作品_添加元素_课课家...
  8. 企业会计准则2020版pdf_企业会计准则及应用指南(2017版)
  9. 计算机图形学——大作业
  10. 学习 PixiJS — 动画精灵
  11. dot全称_dot是什么格式
  12. 正则表达式叠字,过滤重复字
  13. 32怎么通过一个按键实现不同工作模式_游戏工作室防封IP,免费领!!!魔兽世界怀旧版独享IP免费送...
  14. MATLAB 面向对象编程(十二)抽象类
  15. HER608-ASEMI整流二极管R-6轴向插件封装
  16. 统计数据自动补全不存在日期 天
  17. Shell(Bash) - PHP与Sheel交互
  18. mysql数据表关联_MySQL表关联的常用方式有哪几种
  19. 【pytorch】MobileNetV2迁移学习+可视化+训练数据保存
  20. html 超链接 ppt,《用HTML建立超链接》PPT课件.ppt

热门文章

  1. EOS账户系统(6)权限和Action映射
  2. 机器学习(五)——缓解过拟合
  3. Django + Uwsgi + Nginx 的生产环境部署项目知识点
  4. Intel 平台编程总结----缓存的优化
  5. 2020-11-28(不定参数的函数)
  6. 学了这些技术就能轻松找到一份待遇不错的岗位
  7. python使用tomorrow实现多线程
  8. 160个Crackme006
  9. MySQL检查约束(CHECK)
  10. 数据结构—分别用头插法和尾插法建立单链表