Java三种方式实现栈和队列
栈:LIFO(后进先出)
队列:FIFO(先进先出)
1、栈:LIFO(后进先出)
1.1、栈的顺序存储结构实现:
/**
* 基于数组实现的顺序栈
* @param <E>
*/
public class Stack<E> {
private Object[] data = null;
private int maxSize=0; //栈容量
private int top =-1; //栈顶指针 /**
* 构造函数:根据给定的size初始化栈
*/
Stack(){
this(10); //默认栈大小为10
} Stack(int initialSize){
if(initialSize >=0){
this.maxSize = initialSize;
data = new Object[initialSize];
top = -1;
}else{
throw new RuntimeException("初始化大小不能小于0:" + initialSize);
}
} //判空
public boolean empty(){
return top==-1 ? true : false;
} //进栈,第一个元素top=0;
public boolean push(E e){
if(top == maxSize -1){
throw new RuntimeException("栈已满,无法将元素入栈!");
}else{
data[++top]=e;
return true;
}
} //查看栈顶元素但不移除
public E peek(){
if(top == -1){
throw new RuntimeException("栈为空!");
}else{
return (E)data[top];
}
} //弹出栈顶元素
public E pop(){
if(top == -1){
throw new RuntimeException("栈为空!");
}else{
return (E)data[top--];
}
} //返回对象在堆栈中的位置,以 1 为基数
public int search(E e){
int i=top;
while(top != -1){
if(peek() != e){
top --;
}else{
break;
}
}
int result = top+1;
top = i;
return result;
}
}
1.2、栈的链式存储结构实现:
public class LinkStack<E> {
//链栈的节点
private class Node<E>{
E e;
Node<E> next;
public Node(){}
public Node(E e, Node next){
this.e = e;
this.next = next;
}
}
private Node<E> top; //栈顶元素
private int size; //当前栈大小
public LinkStack(){
top = null;
}
//当前栈大小
public int length(){
return size;
}
//判空
public boolean empty(){
return size==0;
}
//入栈:让top指向新创建的元素,新元素的next引用指向原来的栈顶元素
public boolean push(E e){
top = new Node(e,top);
size ++;
return true;
}
//查看栈顶元素但不删除
public Node<E> peek(){
if(empty()){
throw new RuntimeException("空栈异常!");
}else{
return top;
}
}
//出栈
public Node<E> pop(){
if(empty()){
throw new RuntimeException("空栈异常!");
}else{
Node<E> value = top; //得到栈顶元素
top = top.next; //让top引用指向原栈顶元素的下一个元素
value.next = null; //释放原栈顶元素的next引用
size --;
return value;
}
}
}
1.3、基于LinkedList实现的栈结构:
import java.util.LinkedList; /**
* 基于LinkedList实现栈
* 在LinkedList实力中只选择部分基于栈实现的接口
*/
public class StackList<E> {
private LinkedList<E> ll = new LinkedList<E>(); //入栈
public void push(E e){
ll.addFirst(e);
} //查看栈顶元素但不移除
public E peek(){
return ll.getFirst();
} //出栈
public E pop(){
return ll.removeFirst();
} //判空
public boolean empty(){
return ll.isEmpty();
} //打印栈元素
public String toString(){
return ll.toString();
}
}
2、队列:FIFO(先进先出)
2.1 队列的顺序存储结构实现
public class Queue<E> {
private Object[] data=null;
private int maxSize; //队列容量
private int front; //队列头,允许删除
private int rear; //队列尾,允许插入
//构造函数
public Queue(){
this(10);
}
public Queue(int initialSize){
if(initialSize >=0){
this.maxSize = initialSize;
data = new Object[initialSize];
front = rear =0;
}else{
throw new RuntimeException("初始化大小不能小于0:" + initialSize);
}
}
//判空
public boolean empty(){
return rear==front?true:false;
}
//插入
public boolean add(E e){
if(rear== maxSize){
throw new RuntimeException("队列已满,无法插入新的元素!");
}else{
data[rear++]=e;
return true;
}
}
//返回队首元素,但不删除
public E peek(){
if(empty()){
throw new RuntimeException("空队列异常!");
}else{
return (E) data[front];
}
}
//出队
public E poll(){
if(empty()){
throw new RuntimeException("空队列异常!");
}else{
E value = (E) data[front]; //保留队列的front端的元素的值
data[front++] = null; //释放队列的front端的元素
return value;
}
}
//队列长度
public int length(){
return rear-front;
}
}
2.2、循环队列的顺序存储结构实现
import java.util.Arrays;
public class LoopQueue<E> {
public Object[] data = null;
private int maxSize; // 队列容量
private int rear;// 队列尾,允许插入
private int front;// 队列头,允许删除
private int size=0; //队列当前长度
public LoopQueue() {
this(10);
}
public LoopQueue(int initialSize) {
if (initialSize >= 0) {
this.maxSize = initialSize;
data = new Object[initialSize];
front = rear = 0;
} else {
throw new RuntimeException("初始化大小不能小于0:" + initialSize);
}
}
// 判空
public boolean empty() {
return size == 0;
}
// 插入
public boolean add(E e) {
if (size == maxSize) {
throw new RuntimeException("队列已满,无法插入新的元素!");
} else {
data[rear] = e;
rear = (rear + 1)%maxSize;
size ++;
return true;
}
}
// 返回队首元素,但不删除
public E peek() {
if (empty()) {
throw new RuntimeException("空队列异常!");
} else {
return (E) data[front];
}
}
// 出队
public E poll() {
if (empty()) {
throw new RuntimeException("空队列异常!");
} else {
E value = (E) data[front]; // 保留队列的front端的元素的值
data[front] = null; // 释放队列的front端的元素
front = (front+1)%maxSize; //队首指针加1
size--;
return value;
}
}
// 队列长度
public int length() {
return size;
}
//清空循环队列
public void clear(){
Arrays.fill(data, null);
size = 0;
front = 0;
rear = 0;
}
}
2.3、队列的链式存储结构实现
public class LinkQueue<E> {
// 链栈的节点
private class Node<E> {
E e;
Node<E> next;
public Node() {
}
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
}
private Node front;// 队列头,允许删除
private Node rear;// 队列尾,允许插入
private int size; //队列当前长度
public LinkQueue() {
front = null;
rear = null;
}
//判空
public boolean empty(){
return size==0;
}
//插入
public boolean add(E e){
if(empty()){ //如果队列为空
front = new Node(e,null);//只有一个节点,front、rear都指向该节点
rear = front;
}else{
Node<E> newNode = new Node<E>(e, null);
rear.next = newNode; //让尾节点的next指向新增的节点
rear = newNode; //以新节点作为新的尾节点
}
size ++;
return true;
}
//返回队首元素,但不删除
public Node<E> peek(){
if(empty()){
throw new RuntimeException("空队列异常!");
}else{
return front;
}
}
//出队
public Node<E> poll(){
if(empty()){
throw new RuntimeException("空队列异常!");
}else{
Node<E> value = front; //得到队列头元素
front = front.next;//让front引用指向原队列头元素的下一个元素
value.next = null; //释放原队列头元素的next引用
size --;
return value;
}
}
//队列长度
public int length(){
return size;
}
}
2.4、基于LinkedList实现队列结构
/**
* 使用java.util.Queue接口,其底层关联到一个LinkedList(双端队列)实例.
*/
import java.util.LinkedList;
import java.util.Queue; public class QueueList<E> {
private Queue<E> queue = new LinkedList<E>(); // 将指定的元素插入此队列(如果立即可行且不会违反容量限制),在成功时返回 true,
//如果当前没有可用的空间,则抛出 IllegalStateException。
public boolean add(E e){
return queue.add(e);
} //获取,但是不移除此队列的头。
public E element(){
return queue.element();
} //将指定的元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,
//此方法通常要优于 add(E),后者可能无法插入元素,而只是抛出一个异常。
public boolean offer(E e){
return queue.offer(e);
} //获取但不移除此队列的头;如果此队列为空,则返回 null
public E peek(){
return queue.peek();
} //获取并移除此队列的头,如果此队列为空,则返回 null
public E poll(){
return queue.poll();
} //获取并移除此队列的头
public E remove(){
return queue.remove();
} //判空
public boolean empty() {
return queue.isEmpty();
}
}
Java三种方式实现栈和队列的更多相关文章
- Java 三种方式实现接口校验
方法一:AOP 代码如下定义一个权限注解 package com.thinkgem.jeesite.common.annotation; import java.lang.annotation.Ele ...
- 执行ANT JAVA三种方式
1. 命令行 <target name="reporttoexcel" depends="report"> <exec executable= ...
- 0036 Java学习笔记-多线程-创建线程的三种方式
创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...
- java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))
1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...
- Struts2-从值栈获取list集合数据(三种方式)
创建User封装数据类 public class User { private String username; private String password; public String getP ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- Java设置session超时(失效)的三种方式
1. 在web容器中设置(此处以tomcat为例) 在tomcat-6.0\conf\web.xml中设置,以下是tomcat 6.0中的默认配置: <!-- ================= ...
- Java中 实现多线程成的三种方式(继承,实现,匿名内部类)
---------------------------------------------------------------------------------------------------- ...
- java中遍历集合的三种方式
第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...
随机推荐
- posix,perl正则表达式区别
1.正则表达式(Regular Expression,缩写为regexp,regex或regxp),又称正规表达式.正规表示式或常规表达式或正规化表示法或正规表示法,是指一个用来描述或者匹配一系列符合 ...
- (一)linux定时任务的设置 crontab 基础实践
为当前用户创建cron服务 1. 键入 crontab -e 编辑crontab服务文件 例如 文件内容如下: */2 * * * * /bin/sh /home/admin/jiaoben/bu ...
- How to distribute a database among microservices
在为相对复杂的企业域构建微服务时,我们需要找到在这个域中不同责任的边界.在每个边界中,我们会创建领域模型,这个模型是针对业务责任所设计的,并反映了这种业务责任.针对每个边界的数据模型会由同一个边界中的 ...
- WebJars
WebJarsWebJars是一个很神奇的东西,可以让大家以jar包的形式来使用前端的各种框架.组件. 什么是WebJars 什么是WebJars?WebJars是将客户端(浏览器)资源(JavaSc ...
- 一个js小游戏----总结
花了大概一天左右的功夫实现了一个js小游戏的基本功能,类似于“雷电”那样的小游戏,实现了随即怪物发生器,碰撞检测,运动等等都实现了,下一个功能是子弹轨迹,还有其他一些扩展功能,没有用库,也没有用web ...
- 20.如何从app业务逻辑提炼api接口
在app后端的工作中,设计api是一个很考验设计能力的工作.在项目的初始阶段,只知道具体的业务逻辑,那怎么把业务逻辑抽象和提炼,设计出api呢?通过阅读本文,可解答以上疑惑. 在本文中,是用以前做过的 ...
- centos7服务器无GUI情况下安装使用Xvfb、selenium、chrome和selenium-server
最近需要用到selenium浏览器抓取,在windows下对照chrome浏览器开发的代码,在linux服务器上换成phantomjs驱动后,却不能运行了,通过截图发现phantomjs渲染效果和ch ...
- django(权限、认证)系统——用户Login,Logout
上面两篇文章,讲述的Django的Authentication系统的核心模型对象User API和相关的使用,本文继续深入,讨论如何在Web中使用Authentication系统. 前面说了,Djan ...
- Dubbo中编码和解码的解析
(这里做的解析不是很详细,等到走完整个流程再来解析)Dubbo中编解码的工作由Codec2接口的实现来处理,回想一下第一次接触到Codec2相关的内容是在服务端暴露服务的时候,根据具体的协议去暴露服务 ...
- POJ_2318_TOYS&&POJ_2398_Toy Storage_二分+判断直线和点的位置关系
POJ_2318_TOYS&&POJ_2398_Toy Storage_二分+判断直线和点的位置 Description Calculate the number of toys th ...