Bootstrap

双向链表实现栈和队列

栈和队列

  • 栈:先进后出
  • 队列:先进先出

双向链表

定义双向链表的节点

//定义双向链表
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();
    }
}
;