java 栈 先进后出_数据结构: 先进后出——堆栈
栈是一种常用的数据结构,在生活中经常遇到这样的例子,如铁路调度站。本节将详细介绍堆栈的实现过程。
算法点拨(顺序栈)
栈是一种重要的数据结构。从数据结构的角度看,栈也是线性表,其特殊性在于栈的基本操作是线性表操作的子集,它们是操作受限的线性表,因此可以称为限定性的数据结构。其操作是限定在表尾进行插入和删除操作,允许操作的一端称为栈顶。栈的结构如图11.09所示:
图11.09 栈的结构
实现栈首先需要实现一个栈内元素,关键代码如下:
Java代码
public class Stack {
private int maxSize;
private int stackArray[];
private int top=-1;
public Stack(int s){ //构造方法
maxSize=s;
stackArray=new int[maxSize];
}
}
说明:
上述代码中,公共成员stackArray用于储存栈中的数据,top用于存储下一个数据元素的指针。对于栈的操作,无非是进行数据元素的入栈与出栈。
1.查找栈中元素
在进行栈中元素查找时,通常根据栈中元素的数据查找节点。要实现栈中元素的查找,首先需要解决的问题就是遍历栈中的所有元素。可以从栈顶开始,利用循环的方式向下查找,只要不到栈底就可循环查找。
2.入栈操作
入栈操作前面说过,只能在栈顶操作。先将top指针向后移动一个单位,然后将想要入栈的数据元素放到原来top指针所指向的元素位置即可。这样就实现了对栈的入栈操作。操作流程如图11.10所示:
图11.10 入栈操作示意图
3.出栈操作
出栈操作和入栈操作的限定差不多,只是将整个过程反过来进行。先将数据元素释放掉,然后在进行指针的操作,将栈顶指针top向前移动一个位置,使其位置在其原来所指向的位置。将栈顶元素的指针域的指针的指向位置变为原来元素的指向位置。出栈的操作流程如图11.11所示
图11.11 删除节点示意图
算法实现
栈是限定仅在表尾进行插入或删除操作的线性表。因此对栈来说,表尾端有其特殊含义。
例11.3 实现栈的算法
首先需要实现自定义的数据元素类,该类的实现方法可以参看本节算法点拨中的代码。
定义数据元素之后,开始栈的操作编程了。在类中,采用了push,pop,isEmpty,isfull,等方法进行入栈,出栈,判断栈是否为空,判断栈是否满和对栈进行输出。
向栈中添加数据的代码如下:
Java代码
public void push(int j){ //入栈方法
stackArray[++top]=j; //栈顶指针后移
}
对栈进行出栈的操作的代码如下:
Java代码
public int pop(){ //出栈方法
return stackArray[top--]; //栈顶指针前移
}
对栈是否为空和是否已满以及输出的判断代码如下:
Java代码
public boolean isEmpty(){ //判断栈是否为空
return (top==-1);
}
public boolean isFull(){ //判断栈是否为满
return (top==maxSize-1);
}
public void s(int d){ //输出栈中内容
System.out.println("栈序列:");
for(int i=0;i
System.out.print(stackArray[i]+" ");
}
}
为了检查创建栈操作的正确性,特别创建了一个名称为StackTest的类,测试栈的入栈和出栈的操作,其关键代码如下:
Java代码
package stack;
public class StackTest {
public static void main(String[] args) {
int i=0;
Stack s=new Stack(20);
if(!s.isFull()){ //判断栈是否满,没满则调用入栈方法
s.push(100);i++;
s.push(23);i++;
s.push(45);i++;
s.push(78);i++;
s.s(i);
}
System.out.println("\n");
System.out.println("出栈序列:");
while(!s.isEmpty()){ //判断栈是否为空,非空则调用出栈方法
int k=s.pop();
System.out.print(k+" ");
}
}
}
运行上面的代码后,在控制台输出的信息如图11.12所示。
图11.12 运行测试类后在控制台输出的栈中的数据
算法点拨(两栈共享空间)
在一个程序中如果需要同时使用具有相同数据类型的两个栈时,我们觉得最直接的办法就是,同时开辟出两块空间,建立两个栈,但是这样有时会出现,一个栈已经栈满溢出了,而另一个栈确实空余出大量的存储空间,这样会造成大量存储空间的浪费。现在我们可以找一种解决的方法,那就是:两栈共享空间。我们使用一个数组来存储两个栈,让一个栈的栈底为数组的始端,另一个栈的栈底为数组的末端,每个栈的栈顶都向中间延伸。两栈共享空间的结构如图11.13所示:
图11.13 栈的结构
实现栈首先需要实现一个栈内元素,关键代码如下:
Java代码
public class Stack {
private int maxSize;
private int stackArray[];
private int top=-1;
public Stack(int s){ //构造方法
maxSize=s;
stackArray=new int[maxSize];
}
}
说明:
上述代码中,公共成员stackArray用于储存栈中的数据,top用于存储下一个数据元素的指针。对于栈的操作,无非是进行数据元素的入栈与出栈。
1.查找共享空间栈中元素
在进行共享空间的栈中元素查找时,首先我们先要确定我们是要查找哪一个栈中的元素,然后的操作就和顺序栈基本一样了。
2.入栈操作
两栈共享空间的入栈操作也是我们要先确定我们要对哪一个栈进行操作。入栈操作前面我们在顺序栈中已经说过,只能在栈顶操作。例如我们选择对栈一进行操作,先将top1指针向后移动一个单位,然后将想要入栈的数据元素放到原来top1指针所指向的元素位置即可。这样就实现了对栈的入栈操作。操作流程如图11.14所示:
图11.14 入栈操作示意图
3.出栈操作
对于共享空间栈的出栈操作和入栈操作的限定差不多,只是将整个过程反过来进行。先将数据元素释放掉,然后在进行指针的操作,将栈顶指针top1向前移动一个位置,使其位置在其原来所指向的位置。将栈顶元素的指针域的指针的指向位置变为原来元素的指向位置。出栈的操作流程如图11.15所示
图11.15 删除节点示意图
算法实现
栈是限定仅在表尾进行插入或删除操作的线性表。因此对栈来说,表尾端有其特殊含义。
例11.4 实现栈的算法
首先需要实现自定义的数据元素类,该类的实现方法可以参看本节算法点拨中的代码。
定义数据元素之后,开始栈的操作编程了。在类中,采用了push,pop,isEmpty,isfull,s等方法进行入栈,出栈,判断栈是否为空,判断栈是否满和对栈进行输出。
向栈中添加数据的代码如下:
Java代码
public int bos(int i,int x){
int top1=0,top2=stackArray.length-1;
if(top1==top2){
System.out.println("元素溢出!");
}
if(i==1){ //如果操作栈1
return stackArray[++top1]=x;
}
if(i==2){ //如果操作栈2
return stackArray[--top2]=x;
}
return x; //返回插入的数
}
对栈进行出栈的操作的代码如下:
Java代码
public int bpop(int i){
if(i==1){ //如果是栈1
if(top1==-1){
System.out.println("下溢!");
}
return stackArray[top1--]; //栈顶回缩一位
}
if(i==2){ //如果是栈2
if(top2==stackArray.length){
System.out.println("下溢!");
}
return stackArray[top2++]; //栈顶后退一位
}
return i;
}
算法点拨(链栈)
栈的链接存储被称之为链栈。通常我们会用单链表进行对栈的存储,因此其结构特点与单链表的结构特点基本相同。因为只能在栈顶进行插入和删除操作,这样我们就可以使用单链表的表头作为栈的栈顶是最为方便的。其操作流程如图11.16所示:
图11.16 链栈流程图
1.查找链栈中元素
对链栈进行查找操作,其本质上和对链表的查找操作是一样的,只是限定了其只可以从一端进行操作,从表头查起就可以了。
2.入栈操作
对于链栈的入栈操作,其实就是单链表的操作的简化。我们只需要考虑栈顶的操作也就是第一位置的情况。操作流程如图11.17所示:
图11.17 入栈操作示意图
3.出栈操作
对于链栈的出栈,其操作也是很简单的,也是基于单链表的基本操作,也是仅仅是对第一位置的操作,不用考虑其他位置。出栈的操作流程如图11.18所示
图11.18 删除节点示意图
算法实现
链栈是限定仅在表尾进行插入或删除操作的线性表。因此对栈来说,表尾端有其特殊含义。
例11.5 实现栈的算法
首先需要实现自定义的数据元素类,该类的实现方法可以参看本节算法点拨中的代码。
定义数据元素之后,开始栈的操作编程了。在类中,采用了push,pop,isEmpty,isfull,s等方法进行入栈,出栈,判断栈是否为空,判断栈是否满和对栈进行输出。
实现链表首先需要实现一个节点类,关键代码如下:
Java代码
package stack;
public class Node {
public Node next; //指向下一个元素的指针域
public int values; //存储元素的本身数据
public Node(){
int value = 0;
values=value;
}
}
说明:
上述代码中,公共成员Value用于储存节点本身的数据,Next用于存储下一个节点的指针。
对于链栈的操作,无非是进行节点的插入和删除操作对栈进行出栈的操作的代码如下:
Java代码
package stack;
public class Lstack {
Node top=new Node();
public void lpush(){
int x=0;
Node s=new Node(); //申请一个新的节点
s.values=x;
s.next=top; //将节点s插在栈顶
top=s;
}
public int lpop(){
int x=0;
Node p=new Node();
if(top==null){
System.out.println("下溢!");
}
x=top.values; //暂存栈顶元素
p=top; //将栈顶元素摘链
top=top.next;
return x;
}
}
java 栈 先进后出_数据结构: 先进后出——堆栈相关推荐
- java栈 迷宫_数据结构—迷宫(栈实现版)
// // main.c // reo // // Created by 郭瞾阳 on 14-8-13. // Copyright (c) 2014年 gzy. All rights reserved ...
- java 栈 先进先出_堆是先进先出,栈是先进后出
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于C ...
- java栈的回收_JAVA的堆栈和内存、垃圾回收解说
1.有关java健壮性特点的真相 很多书上都说java健壮性的特点是因为java使用数组代替了c++的指针:c++最令人头痛的问题就是内存问题,java的健壮性使编程人员不用再考虑内存的问题:这种观点 ...
- java链表实现_数据结构——基于java的链表实现(真正理解链表这种数据结构)...
一.链表介绍 1.什么是链表? 链表是一种物理存储结构上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.如下图所示,在数据结构中,a1里面的指针存储着a2的地址,这样一个 ...
- java栈 迷宫_利用栈实现迷宫的求解
问题描述:这时实验心理学中的一个典型的问题,心理学家吧一只老鼠从一个无顶的大盒子的入口处赶进迷宫.迷宫设置很多隔壁,对前进方向形成了许多障碍,心理学家在迷宫的唯一出口处放置了一块奶酪,吸引老鼠仔迷宫中 ...
- c++数据结构队列栈尸体_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)...
第三章:栈和队列 下面讲解栈的应用主要内容有:栈的应用.括号匹配.中 后 前 缀表达式转换 1.栈的应用 1.1括号匹配 我们在数学运算中 [(A+b)*c] - (E-F) 往往都会有[ ] 和 ( ...
- java环形链表_数据结构和算法(四)Java实现环形链表
1. 数据结构和算法(四)Java实现环形链表 1.1 约瑟夫问题 约瑟夫问题:公元66年,约瑟夫不情愿地参与领导了犹太同胞反抗罗马统治的起义,后来起义失败,他和一些宁死不降的起义者被困于一个山洞之中 ...
- c++数据结构队列栈尸体_数据结构-栈与队列(二)
1.设有编号为1,2,3,4 的四辆列车,顺序进入一个栈式结构的站台,如图3.90所示.具体写出这四辆列车开出车站的所有可能的顺序,设栈容量为2. 1234 1243 1324 1342 2134 2 ...
- java城市链表_数据结构城市链表 1. 城市链表
[问题描述]将若干城市的信息 联合开发网 - pudn.com...
数据结构城市链表 所属分类:文章/文档 开发工具:Java 文件大小:174KB 下载次数:7 上传日期:2017-12-18 18:37:53 上 传 者:叁佰 说明: 1. 城市链表 [问题描述 ...
最新文章
- 笔记。------数组
- live555 源码分析: SETUP 的处理
- Windows应急响应操作手册
- 最佳适配算法和最差适配算法_影响开放社区的最佳(和最差)方法
- 6月14日Linux设备驱动开发免费讲座PPT
- 5种方式将机器学习带到Java、Python以及Go等编程语言
- 在Java中的foreach循环中调用remove
- 【笔记】编译报错error: cannot convert ‘main(int, char**)::sockadrr*’ to ‘const sockaddr*’ for
- oracle循环视频教程,Oracle高清视频课程全45集,赶紧收藏吧!
- Qt学习-------常用控件
- ios uiswitch 开关_IOS开发(四):开关控件UISwitch
- 服务器系统试用,“雪豹”安装篇(3)
- R语言快速画出ROC曲线和算出可信区间和p值
- 九爷带你部署Mfs分布式文件系统
- Espresso Idling Resource 使用
- 苹果电脑如何同时运行Mac和Windows--pd18
- MLCC(贴片)电容啸叫分析
- 整理了300个市面上最不常见的springboot计算机毕业设计选题。满满的干货
- 与日历有关的小程序推荐
- mysql relaylog_MySQL relay log 详细参数解释
热门文章
- 英语口语week 14 Thursday
- 计算机系统基础 数据的表示和存储
- 互联网,可预见的未来
- SendMessage、PostMessage原理和源代码详解
- SSH (Secure Shell)详解
- CSS Framework 960 Grid System (收)
- [转载] 手工制作Win7 OEM版
- mybatis大于小于等于
- JS window对象 Location对象 location用于获取或设置窗体的URL,并且可以用于解析URL。 语法: location.[属性|方法]...
- Elasticsearch 搜索不到数据问题(_mapping 设置)