栈是一种常用的数据结构,在生活中经常遇到这样的例子,如铁路调度站。本节将详细介绍堆栈的实现过程。

算法点拨(顺序栈)

栈是一种重要的数据结构。从数据结构的角度看,栈也是线性表,其特殊性在于栈的基本操作是线性表操作的子集,它们是操作受限的线性表,因此可以称为限定性的数据结构。其操作是限定在表尾进行插入和删除操作,允许操作的一端称为栈顶。栈的结构如图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;

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/452897.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/452897.shtml
英文地址,请注明出处:http://en.pswp.cn/news/452897.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot—07应用application.properties中的配置

方法1Value("${test.msg}") private String msg;方法2Autowired private Environment env; String value env.getProperty("test.msg");方法3RequestMapping(path"/${query.all}.json", methodRequestMethod.GET) ResponseBody public List&…

skip与direct模式区别 ,他们与CBP的关系

1 CBP表示残差的编码状态,CBP一共6bit,低4位表示4个亮度8x8块,第4位表示U,第五位表示V,如果相应的位为"1", 表示此块有残差系数,反之没有残差,此宏块没有被编码.2 direct 是帧间宏块的一种预测模式,而不是宏块类型,而 S…

程序的装入和链接过程

从用户放入源程序进入操作系统到相应的装程序在机器上运行,所经历的主要阶段有编译阶段 链接阶段 装入阶段 和运行阶段

[零基础学JAVA]Java SE应用部分-34.Java常用API类库

本季目标1、StringBuffer类 2、Runtime 类 3、包装类与JDK 1.5的新特性——泛型 4、日期的操作类 5、Math类 6、Random类1、StringBuffer(重点) String 类的时候说过:String 类的内容一旦声明则不可改变,改变的只是其地址。…

我所理解的机器学习

各位请移步到【http://www.cnblogs.com/cchHers/p/8945908.html】转载于:https://www.cnblogs.com/cchHers/p/8933042.html

protobuf java文档_Java中使用Protobuf

gradle依赖库:implementation com.google.protobuf:protobuf-java:3.4.0implementation com.google.protobuf:protobuf-java-util:3.4.00.编写.proto文件,编译生成对应Java源文件:syntax "proto2";option java_generic_services …

python 数组和列表的区别

Python没有数组: 只有元组(tuple)和列表(list);元组一旦创建不可改变,例如:aatuple(1,2,3);元组不能追加(append)元素,弹出(pop)元素等;只能对元组中的元素进行索引aa[0],不能对其中…

内存空间 逻辑地址空间 相对地址 绝对地址

内存空间(物理空间或绝对空间):由一系列存储单元所限定 的地址范围。 逻辑地址空间(地址空间):由程序中逻辑地址组成的地址范围。 相对地址(逻辑地址):用户程序经编译后…

多租户表设计

2019独角兽企业重金招聘Python工程师标准>>> multi-tenant-databases-in-the-cloudtips-amp-tricks-to-build-multi-tenant-databases-with-sql-databases团队开发框架实战—多租户支持转载于:https://my.oschina.net/yangjiandong/blog/1612626

java 读取webapp文件_在Java Webapp和Java Normal应用中读取公共外部属性文件

但是,我们有以下一些特殊要求,Webapp将部署到tomcat。格式为.jar的普通Java应用程序将放在/ myapp文件夹下myappConfig.property文件将放置在/ myapp下客户端计算机上的目录结构/myapp/myapp.jar/assests/myappConfig.property/tomcat/webapps/myapp.war…

CSS实现树形结构 + js加载数据

看到一款树形结构&#xff0c;比较喜欢它的样式&#xff0c;就参照它的外观自己做了一个&#xff0c;练习一下CSS。 做出来的效果如下&#xff1a; 拉莫小学 一年级 一班二班二年级三年级 一班二班三班树的dom结构&#xff1a; <div class"tree"><ul><…

python中__init__函数以及参数self

1.class类包含&#xff1a; 类的属性&#xff1a;类中所涉及的变量 类的方法&#xff1a;类中函数 2. _init_函数&#xff08;方法&#xff09; 首先说一下&#xff0c;带有两个下划线开头的函数是声明该属性为私有,不能在类地外部被使用或直接访问。init函数&#xff08;方…

程序的装入方式

1 绝对装入方式 2 可重定位装入方式 3 动态运行时装入方式

嵌套集合模型(Nested set model)介绍

原文链接&#xff1a;www.pilishen.com/posts/an-in… 此文档是 nestedset-无限分类正确姿势的扩展阅读 本文翻译自维基百科Nested set model nested set model(嵌套集合模型)是一种在关系型数据库中表示nested sets&#xff08;嵌套集合&#xff09; 的特殊技术。[nested sets…

互联网商业模式:增值还是减值?

网络可以为服务增值&#xff0c;这是人们的共识。不但是增值&#xff0c;而且是按照用户的平方增值&#xff0c;这是梅特卡夫定律说的。 我认为&#xff0c;网络也可以为服务减值&#xff0c;是按照服务提供商的数量的平方减值。如果按用户增值是网络的第一定律&#xff0c;这…

程序的链接方式

1 静态链接 2 装入时动态链接 3 运行时动态链接

Django中--自定义模型管理器类

BookInfo.objects.all()->objects是一个什么东西呢&#xff1f; 答&#xff1a;objects是models.Manger类的一个对象&#xff0c;是Django帮我自动生成的管理器对象&#xff0c;通过这个管理器可以实现对数据的查询。 自定义管理器之后Django不再帮我们生成默认的objects管…

字符驱动之按键(四:poll机制)

1 采用之前的中断按键法&#xff0c;程序会一直在read函数中死循环。2 使用了poll之后&#xff0c;在一段时间内如果有按键按下就会返回&#xff0c;如果没有按键按下等时间到再返回。3 4 应用程序的open,read,write,poll分别对应了驱动程序的open,read,write和poll。5…

第二章 API的理解和使用

2.1.1全局命令 Key * 查看所有键&#xff0c;(慎用&#xff0c;会把所有键都遍历一次并列出) Dbsize 查看键总数&#xff0c;不会遍历所有键&#xff0c;只是从内置函数中读取一个数 Exists [key] 检查键是否存在 Del [key] 删除键 Expire [key] [seconds] 设置键过期时间 Type…

java uuid 线程安全_java – 在多线程应用程序中生成相同的UUID

我使用UUID.randomUUID().toString()将一个唯一值附加到最终存储在数据库中的字符串,并对其具有唯一约束但是因为我的应用程序是多线程的,所以执行在UUID生成的同时发生,并且最终将相同的UUID附加到字符串并且持久性失败.有没有更好的方法来生成随机字符串,即故障安全方法.我尝…