只能在一端插入元素,也只能在这一端删除元素(栈顶),可以把栈看作一个“水杯”,只能从一端添加元素,也只能从一段删除元素,而且,先进入水杯的水在杯底,后进入水杯的水在杯顶,往出倒水的时候,也是倒出的杯顶的水,栈也是一样,先入栈的元素在栈底,后入栈的元素在栈顶,所以先入栈的元素后出,后入栈的元素先出,这也是栈的特性“先进后出,后进先出”Last In First Out(LIFO),取出元素和添加元素只能在栈顶。
将1 2 3 4 5,一次放入栈中
基于链表实现的栈 – 链式栈
基于数组实现的栈 – 顺序栈(使用较多)
定义一个基于动态数组实现的栈
//基于动态数组实现的顺序栈
public class MyStack<E> {
//记录当前栈的元素个数
private int size;
//实际存储数据的动态数组,此时在栈中只能在数组的尾部添加和删除元素
private List<E> data = new ArrayList<>();
}4.栈的操作
1.向栈中添加一个元素
只能在栈顶添加
/**
* 向当前栈中添加元素 -- >压栈操作
* @param val
*/
public void push(E val){
data.add(val);
size++;
}2.当前从栈顶弹出一个元素
/**
* 弹出当前栈顶元素,返回栈顶元素的值
* @return
*/
public E pop(){
if (isEmpty()){
//栈为空无法弹出
throw new NoSuchElementException(&#34;stack is empty!cannot pop!&#34;);
}
//在数组末尾删除元素
E val = data.get(size - 1);
data.remove(size - 1);
size --;
return val;
}3.查看当前栈顶元素,但不弹出
/**
* 查看当前栈顶元素值,不弹出该元素
* @return
*/
public E peek(){
if (isEmpty()){
throw new NoSuchElementException(&#34;stack is empty!cannot peek!&#34;);
}
return data.get(size - 1);
}二、队列
基于数组实现的队列 – 顺序队列
基于链表实现的队列 – 链式队列
出队操作只能在队列的头部进行,若采用数组实现的队列,每次出队一个元素就得搬移剩下的所有元素向前移动一个单位,此时采用链表实现的队列更适合队列的结构,删除元素只需要删除头结点,添加元素在链表的尾部添加
public interface Queue<E> {
//入队操作
void offer(E val);
//出队操作
E poll();
//查看队首元素
E peek();
boolean isEmpty();
}对于栈来说队列的实现子类是比较多的,比如
FIFO队列
双端队列
循环队列
优先级队列
不管哪个队列都要实现
4.FIFO队列
1.定义一个FIFO队列
// An highlighted block
var foo = &#39;bar&#39;;2.向队列中添加一个元素
public void offer(E val) {
Node<E> node = new Node<>(val);
if (head == null){
head = tail = node;
}else{
//链表的尾插
tail.next = node;
tail = node;
}
size++;
}3.从当前队首出队一个元素
public E poll() {
if (isEmpty()){
throw new NoSuchElementException(&#34;queue is empty! cannot poll!&#34;);
}
//头删
E val = head.val;
Node<E> node = head;
head = head.next;
node.next = node = null;
size--;
return val;
}4.查看当前队列的队首元素
public E peek() {
if (isEmpty()){
throw new NoSuchElementException(&#34;queue is empty!cannot peek!&#34;);
}
return head.val;
}5.循环队列