双向链表实现栈和队列
栈和队列
- 栈:先进后出
- 队列:先进先出
双向链表
定义双向链表的节点
//定义双向链表
public static class Node<T>{
public T value;
Node<T> last;
Node<T> next;
public Node(T data) {
value = data;
}
}
定义双向链表
双向链表的头尾节点的定义
public static class DoubleQueue<T>{
//定义队列头尾节点
Node<T> head;
Node<T> tail;
}
双向链表从头部增加节点的方法
- 用入参对象新建一个节点 cur
- 判断当前双向链表是否为空链表
- 若为空链表,则 head 节点和 tail 节点都为新建的该节点 cur
- 若不为空链表,则 cur 的 next 指针指向原本的 head 节点,原本的 head 的 last 指针指向当前节点 cur
- 当前节点作为新的 head 节点
//从头部加节点
public void addNodeFromHead(T value){
//新建节点
Node<T> cur = new Node<T>(value);
//判断当前链表有无节点,若无,则head和tail都指向当前节点
if (head == null){
head = cur;
tail = cur;
} else {
//若有,则cur的下一个节点指向head,head的上一个节点指向当前节点
// 当前节点改为head节点
cur.next = head;
head.last = cur;
head = cur;
}
}
双向链表从尾部增加节点的方法
- 用入参对象新建一个节点 cur
- 判断当前双向链表是否为空链表
- 若为空链表,则 head 节点和 tail 节点都为新建的该节点cur
- 若不为空链表,则 cur 的 last 指针指向原本的tail节点,原本的 tail 的 next 指针指向当前节点 cur
- 当前节点作为新的 tail 节点
//从尾部加节点
public void addNodeFromTail(T value){
//建立新节点
Node<T> cur = new Node<T>(value);
if (head == null){
//如果队列为空,则head和tail都指向该节点
head = cur;
tail = cur;
} else {
//cur的last指向tail,tail的next指向cur,当前节点改为tail
cur.last = tail;
tail.next = cur;
tail = cur;
}
}
双向链表从头部删除节点的方法
- 判断当前双向链表的状态
- 若为空链表,则结束
- 若不为空链表且只有一个节点,则 head 节点与 tail 节点都指向空即可
- 若不为空且不只有一个节点
- 定义 cur 节点记录当前head节点
- cur 节点的下一节点作为新的 head 节点
- 将新的 head 节点的 last 指针指向 null
- 将 cur 节点的 next 指针指向 null
//从头部删除节点
public T delNodeFromHead(){
if (head == null){
return null;
}else if (head == tail){
//如果队列中只有一个节点
head = null;
tail = null;
return null;
} else {
//记录当前头节点
Node<T> cur = head;
//head的下一个节点作为新的头节点
head = head.next;
//新的head的last指针指向空
head.last = null;
cur.next = null;
return cur.value;
}
}
双向链表从尾部删除节点的方法
- 判断当前双向链表的状态
- 若为空链表,则结束
- 若不为空链表且只有一个节点,则 head 节点与 tail 节点都指向空即可
- 若不为空且不只有一个节点
- 定义 cur 节点记录当前tail节点
- cur 节点的上一节点作为新的 tail 节点
- 将新的 tail 节点的 next 指针指向 null
- 将 cur 节点的 last 指针指向 null
//从尾部删除节点
public T delNodeFromTail(){
if (head == null){
return null;
} else if (head == tail){
head = null;
tail = null;
return null;
} else {
Node<T> cur = tail;
tail = tail.last;
tail.next = null;
cur.last = null;
return cur.value;
}
}
用双向链表实现栈
push时从头进,pop时从头出即可
//从头进,从头删,即为双向链表的栈
public static class MyStack<T>{
private DoubleQueue<T> queue;
public MyStack(){
queue = new DoubleQueue<T>();
}
//入栈 - 从头入
public void push(T value){
queue.addNodeFromHead(value);
}
//出栈 - 从头出
public T pop(){
return queue.delNodeFromHead();
}
}
用双向链表实现队列
push时从头进,pop时从尾出即可
//从头进从尾出即为队列
public static class MyQueue<T>{
private DoubleQueue<T> queue;
public MyQueue(){
queue = new DoubleQueue<T>();
}
//入队 - 从头部入
public void push(T value){
queue.addNodeFromHead(value);
}
//出队,从尾部出
public T pop(){
return queue.delNodeFromTail();
}
}