栈的认识
========
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
由此得出,在实现队列使用的存储方式时,使用链表的时间复杂度更低,那就先创建一个节点类,用来存储数据及下一个节点的地址
public class MyQueue {
// 可以使用内部类,定义在实现类里面
private static class Node {
public int val;
public Node next;
public Node(int val) {
this.val = val;
}
}
private Node head;// 记录头节点
private Node tail; // 记录尾节点
}
实现
======
入队列
入队列分为两种情况
- 第一次入队列,队列是为空的,需要先将头节点和尾节点都指向当前的节点
- 非第一次队列,需要将 tail 的 next 指针指向 当前插入的节点,且 tail 节点 也要更新成当前节点
public void offer(int val) {
// 创建新节点
Node node = new Node(val);
//尾插法 需要判断是不是第一次插入
if (isEmpty()) {
this.head = node;
this.tail = node;
return;
}
this.tail.next = node;
this.tail = node;
}
出队列
出队列也分两种情况
队列为空:如果队列为空,调用出队列的方法时,我们应该抛出一个异常提示
队列不为空:队列不为空,采用头删法,将 head 节点 更新成 head.next 的节点,此时就能达到删除队头元素的效果了.
public int poll() {
//判断是否为空队列的
if (isEmpty()) {
throw new UnsupportedOperationException("队列为空");
}
// 记录要删除对头的元素
int ret = this.head.val;
// 更改 head 指向
this.head = this.head.next;
return ret;
}
取对头元素
我们在前面使用了 head 引用,记录了 队头,所以只需要放回 head 引用的值即可,需要判断队列是否为空,为空的话需要抛出异常提示
public int peek() {
//不要移动first
if (isEmpty()) {
throw new UnsupportedOperationException("链表为空");
}
return this.head.val;