栈和队列在java中的实现

比如你想采用广度优先的方法来遍历二叉树,那你需要一个队列来保存节点,比如你想自己实现递归计算,那你就需要一个栈。栈和队列都是一种功能弱化的线性表。

从逻辑上来看,栈和队列其实是由普通线性表发展而来的,为普通线性表增加一些特殊的限制就可以得到栈和队列了。从功能上来看,栈和队列比普通线性表功能相对弱一些,但在一些特殊的场合下,使用栈和队列会更有利,例如,编译器实现函数调用的时候需要使用栈来存储断电,实现递归算法时也需要使用栈来存储。

栈的英文单词是stack,它代表一种特殊的线性表,这种线性表只能在固定一端(通常认为是线性表的尾端)进行插入、删除操作。

对于栈而言,允许进行插入、删除操作的一端被称为栈顶(top),而另一端则被称为栈底(bottom)。

栈是一种被限制过的线性表,通常不应该提供线性表中的如下方法。

获取指定索引处的元素;

按值查找数据元素的位置;

向指定索引处插入数据元素;

删除指定索引处的数据元素。

从上面这些方法可以看出,栈不应该提供从中间任意位置访问元素的方法。也就是说,栈只允许在栈顶插入、删除元素。

栈的常用操作如下:

初始化:通常是一个构造器,用于创建一个空栈。

返回栈的长度:该方法用于返回栈中数据元素的个数。

入栈:向栈的栈顶插入一个数据元素,栈的长度+1。

出栈:从栈的栈顶删除一个数据元素,线性表长度为-1,该方法通常返回被删除的元素。

访问栈顶元素:返回栈顶的数据元素,但不删除站定元素。

判断栈是否为空:该方法判断栈是否为空,如果栈为空返回true,否则返回false。

请空栈:将栈请空。

顺序存储结构的栈简称为顺序栈,它利用一组地址连续的存储单元依次存放从栈底到栈顶的数据元素。栈底位置固定不变,它的栈顶元素可以直接通过顺序栈底层数组的数组元素arr[size-1]来访问。

类似地,程序可以采用单链表来保存栈中所有元素,这种链式结构的栈也被称为链栈。对于链栈而言,栈顶元素不断地改变,程序只要使用一个top引用来记录当前的栈顶元素即可。top引用变量永远引用栈顶元素,再使用一个size变量记录当前栈中包含多少元素即可。

对于链栈的进栈操作,程序只需要做如下两件事情:

让top引用指向新添加的元素,新元素的next引用指向原来的栈顶元素;

让纪录栈内元素个数的size变量+1。

对于链栈的出栈操作,需要将栈顶元素弹出栈,程序需要做两件事情:

让top引用指向原栈顶的下一个元素,并释放原来的栈顶元素;

让纪录栈内元素个数的size变量-1。

Java集合实际上提供了以下两种栈供开发者使用。

java.util.stack:它就是一个最普通的顺序栈,底层基于数组实现。这个stack类是线程安全的,在多线程环境下也可放心使用。

java.util.linkedlist:linkedlist是一个双向链表,但如果查看该类的api将会发现,它同样提供了push,pop,peek等方法,这表明linkedlist 其实还可以当成栈来使用。linkedlist代表栈的链式实现,但它是线程不安全的,如果需要在多线程环境下使用,应该使用collections类的工具方法将其“改造”成线程安全的类。

队列(queue)是另一种被限制过的线性表,它使用固定的一端来插入数据元素,另一端只用于能删除元素。也就是说,队列中元素的移动方向总是固定的,就像排队购物一样:先进入队伍的顾客先获得服务,队伍中的顾客总是按固定方向移动,只有当排在前面的所有顾客获得服务之后,当前顾客才会获得服务。


队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,只允许在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为对头。

队列的顺序存储结构:系统采用一组地址连续的存储单元依次存放rear端到front端的所有数据元素,程序只需front和rear两个整形变量来记录队列front端的元素索引、rear端的元素索引。

为了重新利用顺序队列底层数组中已删除元素所占用的空间,清除可能出现的"假满"现象,可以将顺序队列改进为循环队列。

双向队列(Deque)代表一种特殊的队列,它可以在两端同时进行插入、删除操作。

JDK提供了一个古老的stack类,但是现在已近不推荐开发者使用这个古老的“栈”实现,而是推荐使用deque实现类作为“栈”的实现。

JDK为deque提供了arrayDeque、LinkedBlockingDeque、LinkedList这3个实现类。其中,arrayDeque代表顺序存储结构的双向队列,linkedlist则代表链式存储结构的双向队列,linkedBlockingDeque其实是一个线程安全的、链式结构的双向队列。

linkedlist代表一种双向的、链式存储结构的循环线性表,这里又提到linkedlist代表线程安全的、链式结构的双向队列,由此可见linkedlist实在是一个功能非常强大的集合类。事实上,linkedlist几乎是java集合框架中方法最多的类。但大多数情况下,使用arraylist、arrayDeque的性能比linkedlist更好。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值