目录
一.栈
栈只有一个出口,元素先进后出,从栈顶进入从栈顶取出,先进的元素先到栈底
栈代码实例:
class Stack{
private int MaxSize; //栈的长度
private long[] SatckArray;
private int top; //栈顶
public Stack(int s){ //初始化栈
MaxSize=s;
SatckArray=new long[MaxSize];
top=-1;
}
public void push(long j){ //入栈
SatckArray[++top]=j;
}
public long pop(){ //出栈
return SatckArray[top--];
}
public long peek(){ //获取栈顶元素
return SatckArray[top];
}
public boolean isEpty(){ //判断栈是否为空
return (top==-1);
}
public boolean isFull(){ //判断栈是否满
return (top==MaxSize-1);
}
}
二.队列
队列是一种数据结构,类似于栈结构,只不过队列结构的数据先进先出(FIFO)
队列代码实例:
class Queue{
private int MaxSize;
private long[] QueArray;
private int front;
private int rear;
private int nltems;
public Queue(int s){ //队列初始化
MaxSize=s;
QueArray=new long[MaxSize];
front=0;
rear=-1;
nltems=0;
}
public void insert(long j){ //元素从队尾入队
if (rear==MaxSize-1) //如果队列满了,重置rear
rear=-1;
QueArray[++rear]=j;
nltems++;
}
public long romve(){ //元素从队首出队
long temp=QueArray[front++];
if (front==MaxSize) //如果移除最后一个元素,重置front
front=0;
nltems--;
return temp;
}
public long peekFront(){ //获取队首
return QueArray[front];
}
public boolean isEmpty(){ //判断是否为空
return (nltems==0);
}
public boolean isFull(){ //判断是队列是否满了
return (nltems==MaxSize);
}
public int size(){ //元素个数
return nltems;
}
}
三.双端队列
双端队列是一种特殊的队列,它两端都可以插入元素,同时两端也都可以取出元素
双端队列代码实例:
class MyDeque<E> {
//默认容量
private static final int DEFAULT_CAPACITY = 8;
//最大容量
private static final int MAX_CAPACITY = Integer.MAX_VALUE;
//存储数组
private Object[] elements;
//队列头
private int head;
//队列尾
private int tail;
//队列元素个数
private int size;
//无参构造器,使用默认容量初始化
public MyDeque() {
//初始化
this.elements = new Object[DEFAULT_CAPACITY];
this.head = 0;
this.tail = 0;
this.size = 0;
}
//指定容量大小的构造器
public MyDeque(int capacity) {
//合法性检查
if (capacity < 0 || capacity > MAX_CAPACITY) {
throw new IllegalArgumentException("parameter is illegal");
}
//使用给定的容量初始化
this.elements = new Object[capacity];
this.head = 0;
this.tail = 0;
this.size = 0;
}
/**
* 在双端队列的开头添加指定的元素。
*
* @param element 要添加的元素
* @return 是否添加成功
*/
public boolean offerFirst(E element) {
//判断队列是否满了
if (size == elements.length) {
doubleCapacity();
}
//如果队列为空
if (isEmpty()) {
elements[head] = element;
} else {
//添加元素到队列头,head左移
elements[getRealIndex(head - 1)] = element;
//更新队列状态
head = getRealIndex(head - 1);
}
size++;
return true;
}
/**
* 在双端队列的尾部添加指定的元素。
*
* @param element 要添加的元素
* @return 是否添加成功
*/
public boolean offerLast(E element) {
//判断队列是否满了
if (size == elements.length) {
doubleCapacity();
}
//如果队列为空
if (isEmpty()) {
elements[tail] = element;
} else {
//添加元素到队列尾,tail右移
elements[getRealIndex(tail + 1)] = element;
//更新队列状态
tail = getRealIndex(tail + 1);
}
size++;
return true;
}
/**
* 返回并删除双端队列的队头元素。如果双端队列为空,则返回null。
*
* @return
*/
public E pollFirst() {
//判断队列是否为空
if (isEmpty()) return null;
//删除除队列的第一个元素
E removedElement = (E) elements[head];
elements[head] = null;
//head右移
head = getRealIndex(head + 1);
size--;
return removedElement;
}
/**
* 返回并删除双端队列的队尾元素。如果双端队列为空,则返回null。
*
* @return
*/
public E pollLast() {
//判断队列是否为空
if (isEmpty()) return null;
//删除除队列的第一个元素
E removedElement = (E) elements[tail];
elements[tail] = null;
//tail左移
tail = getRealIndex(tail - 1);
size--;
return removedElement;
}
/**
* 返回双端队列的第一个元素。如果双端队列为空,则返回null。
*
* @return
*/
public E peekFirst() {
if (isEmpty()) return null;
return (E) elements[head];
}
/**
* 返回双端队列的最后一个元素。如果双端队列为空,则返回null。
*
* @return
*/
public E peekLast() {
if (isEmpty()) return null;
return (E) elements[tail];
}
/**
* 判断队列是否为空
*
* @return true:为空 false:不为空
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 扩增队列容量
*/
public void doubleCapacity() {
//检查队列是否已达到上限
if (elements.length == MAX_CAPACITY) throw new RuntimeException("deque is full");
//新的队列容量为目前的两倍
int newCapacity = elements.length * 2;
//检查新容量是否超过最大容量限制
if (newCapacity > MAX_CAPACITY) newCapacity = MAX_CAPACITY;
//使用新容量构造一个新的数组
Object[] newArr = new Object[newCapacity];
//把元素移动到新的数组中
for (int i = 0; i < elements.length; i++) {
newArr[i] = elements[getRealIndex(head + i)];
}
//更新队列状态
head = 0;
tail = elements.length - 1;
elements = newArr;
}
/**
* 获取真实下标
*
* @param logicIndex 逻辑下标
* @return 真实下标
*/
private int getRealIndex(int logicIndex) {
int innerArrayLength = elements.length;
//逻辑下标小于0
if (logicIndex < 0) {
//加上当前数组的长度
logicIndex += innerArrayLength;
}
//逻辑下标大于等于数组长度
if (logicIndex >= innerArrayLength) {
//减去当前数组的长度
logicIndex -= innerArrayLength;
}
//返回真实下标
return logicIndex;
}
/**
* 打印deque
*/
public void printDeque() {
for (int i = 0; i < elements.length; i++) {
if (elements[getRealIndex(head + i)] == null) break;
System.out.print(elements[getRealIndex(head + i)].toString());
System.out.print("-->");
}
System.out.println("\b\b\b");
}
}
四.优先级队列
和普通队列一样,优先级队列有一个对列头和一个队列尾,但优先级队列的数据按一定的条件给队列中数据排序
优先级队列代码实例:
class priorityQ{
private int MaxSize;
private long[] queArray;
private int nltems;
public priorityQ(int s){ //初始化队列
MaxSize=s;
queArray=new long[MaxSize];
nltems=0;
}
public void inser(long item) {
int j;
if (nltems == 0) {
queArray[nltems++] = item;
} else {
for (j = nltems - 1; j >= 0; j--) {
if (item > queArray[j]) //设置优先级
queArray[j + 1] = queArray[j];
else break;
}
queArray[j + 1] = item;
nltems++;
}
}
public long remove(){
return queArray[--nltems];
}
public long peekmin(){
return queArray[nltems-1];
}
public boolean isEpty(){
return (nltems==0);
}
public boolean isFull(){
return (nltems==MaxSize);
}
}