前言
本章带大家聊一下栈和队列
方法
1.栈的概念
栈(stack),又称堆栈,它是运算受限的线性表。其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行插入、删除、查找等操作。
表中进行插入删除操作的一端称为栈顶(top),栈顶保存的元素称为栈顶元素。相对的,表的另一端称为栈底(bottom)。
当栈中没有数据元素时称为空栈;向一个栈插入元素称为进栈或入栈,从一个栈删除元素称为出栈或退栈。
由于栈的插入和删除操作仅在栈顶进行,后进栈的元素必然先出栈,所以又把堆栈称为后进先出表。
2.栈的存储结构
1)顺序栈
同线性表一样,底层采用数组实现,数组下标大的一端称为栈顶。
2)链栈
同线性表一样,底层采用链表实现,首节点或首节点后面的节点可作为栈顶。
3.队列的概念
队列(queue),简称队,和栈一样,它也是操作受限的线性表。其限制在只允许在表的一点插入,在表的另一端删除。
在队列中,把插入数据元素的一端称为队尾,删除数据元素的一端称为队首。
向队尾插入元素称为进对或入队,从队列中删除元素称为离队或出队。
由于队列的插入和删除操作都必须在队尾和队首进行, 每个元素必须按照进入的次序离队,也就是说先进队的元素必然先离队,所以又称队列为先进先出表。
4.队列的存储结构
1)顺序队列
同线性表一样,底层采用数组实现。
2)链队列
同线性表一样,底层采用链表实现。
5.栈在Java中的实现
说起栈在Java中的实现,那么不得不提一个类,那就是Stack(已过时)
public class Stack<E> extends Vector<E>
由于性能的原因,随着Vector的没落,渐渐的Stack类也就几乎没人用了,由于Stack类内部采用了动态数组的实现方式,那么插入和删除就带来不必要的性能开销,再加上又是同步的,所以开销十分巨大,这对于栈操作来说是致命的。
在Java后续的1.5和1.6中,又再次引入了两个接口:
一个就是队列接口,一个是双端队列接口。
由于双端队列可以作为栈进行操作(仅操作一端即为栈),是目前比较流行的一种栈的实现方式!
官方的API文档也证实了这一点:
我们来看一下这个Deque接口的实现类:
相信大家都不陌生,ArrayDeque代表的是底层采用数组实现,LinkedList则代表底层采用链表实现,很明显,我们操作栈优先使用链式存储结构。
注意:使用栈时请记住操作栈的专用方法(push():入栈;pop():出栈;peek():查询栈顶元素),避免使用其他方法如add(),remove()
栈的操作示例:
package cn.edu.ccut;
import java.util.Deque;
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
//声明一个堆栈(stack),底层采用链式存储结构
Deque<String> stack = new LinkedList<String>();
//入栈操作
stack.push("1");
stack.push("2");
stack.push("3");
//取出栈顶元素
System.out.println(stack.peek());
//出栈操作
stack.pop();
//取出栈顶元素
System.out.println(stack.peek());
}
}
程序运行结果为:
6.队列在Java中的实现
前面已经介绍过队列的接口了,那就是Queue
那么既然该接口是双端队列Deque的父接口,那么其实现类也必然有LinkedList
显然对于队列的操作,我们仍然倾向于使用链式存储结构最为其实现。
注意:使用队列时请记住操作栈的专用方法(offer():入队;poll():出队;peek():查询队首元素),避免使用其他方法如add(),remove()
队列的操作示例:
package cn.edu.ccut;
import java.util.LinkedList;
import java.util.Queue;
public class Test {
public static void main(String[] args) {
//声明一个队列(queue),底层采用链式存储结构
Queue<String> queue = new LinkedList<String>();
//入队操作
queue.offer("1");
queue.offer("2");
queue.offer("3");
//取出队首元素
System.out.println(queue.peek());
//出队操作
queue.poll();
//取出队首元素
System.out.println(queue.peek());
}
}
程序运行结果为:
大家可以仔细的对比栈和队列在操作结果上的差异,仔细消化,学有余力可自行编程实现栈和队列。