栈和队列的Java实现
一、 栈
1、概念
栈是一种特殊的线性表,它只能在栈顶(top)进行插入(push)和删除(pop)操作。
栈的常用操作:
入栈(push):向栈顶插入元素
出栈(pop):从栈顶删除元素
访问栈顶元素(peek):访问栈顶元素
2、 栈的顺序结构的实现
public class SequenceStack<T> { private Object[] elementData; //数组用于承装元素
private int DEFAULT_SIZE = 20; //初始数组默认大小
private int capacity;
private int capacityIncrement = 5;
private int size = 0; //栈中当前容量
public SequenceStack(){
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
public SequenceStack(T element){
this();
elementData[0] = element;
size++;
}
//返回栈的长度
public int length(){
return this.size;
} //入栈操作
public void push(T element){
this.ensureCapacity();
elementData[size] = element;
size++;
} //出栈操作
public T pop(){
T popElement = (T)elementData[size-1];
size--;
return popElement;
} //访问栈顶元素
public T peek(){
return (T)elementData[size-1];
} //判断是否为空
public boolean isEmpty(){
boolean b = false;
if(size == 0){
b = true;
}
return b;
} //清空栈
public void clear(){
for(Object o:elementData){
o = null;
}
size = 0;
} //遍历栈
public void view(){
System.out.print("当前栈中元素为:");
for(int i = 0;i < size;i++){
System.out.print(elementData[i] + " ");
}
System.out.println();
} //栈容量检测与扩充
public void ensureCapacity(){
if(capacityIncrement > 0){
while((size+1) > capacity){
capacity+=capacityIncrement;
}
}
else{
while((size+1) > capacity){
capacity = capacity * 2;
}
}
} public static void main(String[] args) {
SequenceStack<String> sequenceStack = new SequenceStack<> ();
sequenceStack.push("hello");
sequenceStack.push("world");
sequenceStack.push("perfect");
System.out.print("入栈操作后,");
sequenceStack.view();
sequenceStack.pop();
System.out.print("出栈操作后,");
sequenceStack.view();
System.out.println("当前栈顶元素为:" + sequenceStack.peek());
sequenceStack.clear();
System.out.println("clear之后,栈是否为空:" + sequenceStack.isEmpty());
}
}
3、栈的链式结构的实现:
public class LinkedStack<T> { private class Node{
private T data;
private Node next;
public Node(){ }
public Node(T element,Node next){
this.data = element;
this.next = next;
}
} private Node top;
private int size = 0; public LinkedStack(){ } public LinkedStack(T element){
top = new Node(element,null);
size++;
}
//获取栈大小
public int length(){
return size;
}
//入栈操作
public void push(T element){
Node newNode;
newNode = new Node(element, top);
top = newNode;
size++;
}
//出栈操作
public T pop(){
Node oldNode = top;
top = top.next;
oldNode.next = null;
size--;
return oldNode.data;
} //获取栈顶元素
public T peek(){
return top.data;
} //清空栈
public void clear(){
top = null;
size = 0;
} public boolean isEmpty(){
if(size == 0){
return true;
}
return false;
} //遍历栈中元素
public void view(){
Node currentNode = top;
System.out.print("栈中元素为:");
while(currentNode != null){
System.out.print(currentNode.data + " ");
currentNode = currentNode.next;
}
System.out.println();
} public static void main(String[] args) {
LinkedStack<String> linkedStack = new LinkedStack<>();
linkedStack.push("hello");
linkedStack.push("world");
linkedStack.push("perfect");
System.out.print("入栈操作后,");
linkedStack.view();
linkedStack.pop();
System.out.print("出栈操作后,");
linkedStack.view();
System.out.println("当前栈顶元素为:" + linkedStack.peek());
linkedStack.clear();
System.out.println("clear之后,栈是否为空:" + linkedStack.isEmpty());
}
}
三、 队列
1、概念
队列是一种被限制的线性表,它只允许在表的前端(front,即队尾)进行删除操作,只允许在表的后端(rear,即队头)进行插入操作
常用操作:
加入元素:向队列rear端插入元素
删除元素:从队列的front端删除元素
访问队列front端元素:
2、队列的顺序存储结构及实现
public class SequenceQueue<T> { private int DEFAULT_SIZE = 20;
private int capacity;
private int front = 0;
private int rear = 0;
private Object[] elementData;
public SequenceQueue(){
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
public SequenceQueue(T element){
this();
elementData[0] = element;
rear++;
}
// 获取队列长度
public int length(){
return rear-front;
} //向队列尾添加元素
public void add(T element){
if(rear > capacity-1){
throw new IndexOutOfBoundsException("队列已满");
}
elementData[rear++] = element;
} //删除队列头元素
public T remove(){
if((rear-front) == 0){
throw new IndexOutOfBoundsException("队列为空,不能删除");
}
T remove = (T)elementData[front];
elementData[front++] = null;
return remove;
} //获取队列头部元素
public T getElement(){
return (T)elementData[front];
} //判断队列是否为空
public boolean isEmpty(){
return (rear-front) == 0;
} //清空队列
public void clear(){
Arrays.fill(elementData, null);
front = 0;
rear = 0;
} //遍历队列
public void view(){
System.out.print("队列中元素为:");
for(int i = front;i < rear; i++){
System.out.print(elementData[i] + " ");
}
System.out.println();
} public static void main(String[] args) {
SequenceQueue<String> sequenceQueue = new SequenceQueue<> ();
sequenceQueue.add("hello");
sequenceQueue.add("world");
sequenceQueue.add("perfect");
sequenceQueue.view();
System.out.println("执行remove删除的元素为:" + sequenceQueue.remove());
System.out.println("队列头部元素为:" + sequenceQueue.getElement());
sequenceQueue.clear();
System.out.println("clear之后队列长度:" + sequenceQueue.length()); } }
3、顺序存储结构的循环队列
public class LoopSequenceQueue<T> { private int DEFAULT_SIZE = 5;
private int capacity;
private int front = 0;
private int rear = 0;
private Object[] elementData; public LoopSequenceQueue(){
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
} public LoopSequenceQueue(T element){
this();
elementData[0] = element;
rear++;
} //获取队列长度
public int length(){
if(isEmpty()){
return 0;
}
return rear > front?rear-front:(capacity-(front-rear));
} //向队列中插入元素
public void add(T element){
if(rear == front && elementData[front] != null){
throw new IndexOutOfBoundsException("队列已满");
}
elementData[rear] = element;
rear = (rear+1) > (capacity-1)?0:(++rear);
} //从队列头删除元素
public T delete(){
if(isEmpty()){
throw new IndexOutOfBoundsException("队列为空");
}
T del = (T)elementData[front];
elementData[front] = null;
front = (front+1) > capacity?0:++front;
return del;
} //清空队列
public void clear(){
Arrays.fill(elementData, null);
front = 0;
rear = 0;
} //遍历队列
public void view(){
System.out.print("队列中元素为:");
if(front < rear){
for(int i = front;i < rear;i++){
System.out.print(elementData[i] + " ");
}
}
else{
for(int i = front;i < capacity;i++)
System.out.print(elementData[i] + " ");
for(int i = 0;i < rear;i++)
System.out.print(elementData[i] + " ");
}
} //判断队列是否为空
public boolean isEmpty(){
if(front == rear && elementData[front] == null){
return true;
}
return false;
} public static void main(String[] args) {
LoopSequenceQueue<String> loopSequenceQueue = new LoopSequenceQueue<>();
loopSequenceQueue.add("hello");
loopSequenceQueue.add("world");
loopSequenceQueue.add("perfect");
loopSequenceQueue.add("3333333");
loopSequenceQueue.delete();
loopSequenceQueue.add("4444444444");
loopSequenceQueue.add("555555555");
loopSequenceQueue.view();
System.out.println("当前队列长度为:" + loopSequenceQueue.length()); } }
4、队列的链式存储结构
public class LinkedQueue<T> { private class Node{
private T data;
private Node next;
public Node(){ } public Node(T element,Node next){
this.data = element;
this.next = next;
}
} private Node front;
private Node rear;
private int size = 0;
public LinkedQueue(){
this.front = null;
this.rear = null;
} public LinkedQueue(T element){
rear = new Node(element,null);
front = rear;
size++;
}
//获取队列长度
public int length(){
return size;
} //从队尾插入元素
public void add(T element){
Node newNode = new Node(element,null);
if(rear == null){
rear = newNode;
front = rear;
}
else{
rear.next = newNode;
rear = newNode;
} size++;
}
//删除队头元素
public T remove(){
if(size == 0){
throw new IndexOutOfBoundsException("队列为空,不能删除");
}
Node delNode = front;
front = front.next;
delNode.next = null;
size--;
return delNode.data;
} //清空队列
public void clear(){
front = null;
rear = null;
size = 0;
} //遍历队列元素
public void view(){
System.out.print("队列中元素为:");
Node currentNode = front;
while(currentNode != null){
System.out.print(currentNode.data + " ");
currentNode = currentNode.next;
}
System.out.println();
} public static void main(String[] args) {
LinkedQueue<String> linkedQueue = new LinkedQueue<> ();
linkedQueue.add("hello");
linkedQueue.add("world");
linkedQueue.add("perfect");
linkedQueue.add("3333333");
linkedQueue.remove();
linkedQueue.add("4444444444");
linkedQueue.add("555555555");
linkedQueue.view();
System.out.println("当前队列长度为:" + linkedQueue.length()); } }
注:本文部分内容参考自《疯狂Java程序员的基本修养》
栈和队列的Java实现的更多相关文章
- 数据结构之栈和队列及其Java实现
栈和队列是数据结构中非常常见和基础的线性表,在某些场合栈和队列使用很多,因此本篇主要介绍栈和队列,并用Java实现基本的栈和队列,同时用栈和队列相互实现. 栈:栈是一种基于“后进先出”策略的线性表.在 ...
- 算法_栈与队列的Java链表实现
链表是一个递归的数据结构,它或者为null,或者是指向一个结点的引用,该结点含有一个泛型的元素和指向另一个链表的引用.可以用一个内部类来定义节点的抽象数据类型: private class Node ...
- 剑指Offer-5.用两个栈实现队列(C++/Java)
题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 分析: 栈的特点是先进后出,队列的特点则是先进先出. 题目要求我们用两个栈来实现一个队列,栈和队列都有入栈 ...
- 数据结构 1 线性表详解 链表、 栈 、 队列 结合JAVA 详解
前言 其实在学习数据结构之前,我也是从来都没了解过这门课,但是随着工作的慢慢深入,之前学习的东西实在是不够用,并且太皮毛了.太浅,只是懂得一些浅层的,我知道这个东西怎么用,但是要优化.或者是解析,就不 ...
- 两个队列实现栈&两个栈实现队列(JAVA)
1,两个栈实现队列 题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路:栈的特点时先进后出,队列的特点是先进先出. 若此时有两个队列stack1,st ...
- 剑指offer第二版面试题8:用两个栈实现队列(JAVA版)
题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能. 分析: 我们通过一个具体的例子来分析 ...
- 剑指offer 计划1(栈与队列)---java
1.1.题目1 剑指 Offer 09. 用两个栈实现队列 1.2.解法 解法如题目所说.定义两个栈.这里假设第一个栈为a,第二个栈为b. 实现两个函数增加尾和删除头. 增加即直接push入第一个栈. ...
- 栈和队列的java简单实现
今天看了一本书<啊哈 算法>,书的内容不多,一共两章,第一章是常见的排序算法包括桶排序.冒泡排序和快速排序,这些事基础的排序算法网上有很多资料说明,这里主要说第二章栈,对列,链表,书上使用 ...
- 剑指offer-面试题7:俩个栈实现队列(java)
详细分析请参照C语言版,这里仅仅给出实现代码,注释很详细,不得不说java各种api用起来真是爽飞了 1 package com.xsf.SordForOffer; 2 3 import java.u ...
随机推荐
- SQL Server 查看正在运行的事务信息的 2 种方法。
方法 1.sys.dm_tran_session_transactions; 方法 2.dbcc opentran ------------------------------------------ ...
- Can someone explain Webpack's CommonsChunkPlugin
I get the general gist that the CommonsChunkPlugin looks at all the entry points, checks to see if t ...
- Azure File SMB3.0文件共享服务(5)
使用Java管理Azure文件共享服务 Azure文件共享服务提供了多种方式的访问接口,包括Powershell,.Net, Java, Python等等,本章主要介绍如何使用Java来访问A ...
- centos 安装amp 运行环境+配置虚拟地址
一.安装 MySQL 首先来进行 MySQL 的安装.打开超级终端,输入: [root@localhost ~]# yum install mysql mysql-server 安装完毕,让 MySQ ...
- Android doGet方法
DefaultHttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet("http://w ...
- bash 学习笔记(一)
尽量使用printf而不要用echo(echo再不同情况下语义不同) 整数%d,小数后6位%f,科学计数法 %e,16进制 %x 宽度限制 %8s %-15s 正数朝右对齐 负数朝左对齐:%04d\n ...
- linux使用FIO测试磁盘的iops
FIO是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括:sync,mmap, libaio, posixaio, SG v3, splice, null, ...
- 树形控件CTreeCtrl的使用
树形控件在界面编程中应用十分普遍,如在资源管理器中和树形结构显示书的文件夹等,我们一步步研究树形控件的使用. 在对话框界面上首先拖动创建一个树,一般我们改变三个属性: Has Buttons显示带有& ...
- properties文件value换行处理方式
书写方式如下,就可以允许key1的value值换行了,但是整个过程要注意不要在文件中出现任何的非英文非半角的字符 key1=Where did you take the picture?\ ...
- Android简单登录系统
很长时间没有写博客了,最近一直在写android for gis方面的项目.不过这篇博客就不写gis方面的了,今天刚刚做的一个简单的android登录系统.数据库是android自带的sqlite,s ...