知识点(5)——使用LinkedList实现栈和队列

前言

LinkedList是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。

LinkedList 实现 List 接口,能对它进行队列操作。

LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。

LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。

LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。

LinkedList 是非同步的。

一、LinkedList可以作为LIFO(后进先出)的栈,作为LIFO的栈时,下表的方法等价:

栈方法        等效方法
push(e)      addFirst(e)
pop()        removeFirst()
peek()       peekFirst()
/**
  * 将LinkedList当作 LIFO(后进先出)的堆栈
  */
private void useLinkedListAsLIFO() {       
    // 新建一个LinkedList
    LinkedList stack = new LinkedList();

       // 将1,2,3,4添加到堆栈中
      stack.push("1");
      stack.push("2");
      stack.push("3");
      stack.push("4");

      // 打印“栈”
      System.out.println("stack:"+stack);

      // 删除“栈顶元素”
      System.out.println("stack.pop():"+stack.pop());
        
      // 取出“栈顶元素”
      System.out.println("stack.peek():"+stack.peek());

      // 打印“栈”
      System.out.println("stack:"+stack);
}

输出结果:

stack:[4, 3, 2, 1]
stack.pop():4
stack.peek():3
stack:[3, 2, 1]

二、LinkedList可以作为FIFO(先进先出)的队列,作为FIFO的队列时,下表的方法等价:

队列方法       等效方法
add(e)        addLast(e)
offer(e)      offerLast(e)
remove()      removeFirst()
poll()        pollFirst()
element()     getFirst()
peek()        peekFirst()

/**
  * 将LinkedList当作 FIFO(先进先出)的队列
  */
private void useLinkedListAsFIFO() {
      // 新建一个LinkedList
      LinkedList queue = new LinkedList();

      // 将10,20,30,40添加到队列。每次都是插入到末尾
      queue.add("10");
      queue.add("20");
      queue.add("30");
      queue.add("40");

      // 打印“队列”
      System.out.println("queue:"+queue);

      // 删除(队列的第一个元素)
      System.out.println("queue.remove():"+queue.remove());
  
      // 读取(队列的第一个元素)
      System.out.println("queue.element():"+queue.element());

      // 打印“队列”
      System.out.println("queue:"+queue);
 }

输出结果:

queue:[10, 20, 30, 40]
queue.remove():10
queue.element():20
queue:[20, 30, 40]

三、使用两个栈实现一个队列

public class MyQueue {

    /*入队栈*/
    private final Stack inStack = new Stack<>();
    /*出队栈*/
    private final Stack outStack = new Stack<>();

    /**
     * 入队
     *
     * @param e
     */
    public void offer(E e) {
        while (!outStack.isEmpty()) {
            inStack.push(outStack.pop());
        }
        inStack.push(e);
    }

    /**
     * 出队
     */
    public void poll() {
        while (!inStack.isEmpty()) {
            outStack.push(inStack.pop());
        }
        outStack.pop();
    }

    /**
     * 判断队列是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }

    /**
     * 获取队列中的第一个元素
     *
     * @return
     */
    public E peek() {
        while (!inStack.isEmpty()) {
            outStack.push(inStack.pop());
        }
        return outStack.peek();
    }

}

四、用两个队列实现栈

思路:队列是先进先出,栈是先进后出。要想用队列实现栈,则需要两个队列。定义一个是用来存放元素的队列,再定义一个辅助的队列。两个队列的功能需要不停的更换。即现在queue1用来存放元素,但进行完某操作后,queue1可能就用了作为辅助了。

public class MyStack {
    /*存放元素的队列*/
    private Queue queue1 = new LinkedList<>();
    /*辅助队列*/
    private Queue queue2 = new LinkedList<>();

    /**
     * 压栈(将元素e 压入栈顶)
     */
    public void push(E e) {
        queue1.offer(e);
    }

    /**
     * 弹栈(移除并返回栈顶元素)
     *
     * @return
     */
    public E pop() {
        for (int i = 0; i < queue1.size() - 1; i++) {
            queue2.offer(queue1.poll());
        }
        E lastE = queue1.poll();

        Queue temp = queue1;
        queue1 = queue2;
        queue2 = temp;
        return lastE;
    }

    /**
     * 获取栈顶元素
     *
     * @return
     */
    public E peek() {
        for (int i = 0; i < queue1.size() - 1; i++) {
            queue2.offer(queue1.poll());
        }
        E lastE = queue1.poll();
        queue2.offer(lastE);

        Queue temp = queue1;
        queue2 = queue1;
        queue1 = temp;

        return lastE;
    }

    /**
     * 判断栈内是否有元素
     *
     * @return
     */
    public boolean isEmpty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

五、Java实现栈

(1)方式一:数组的方式实现:

public class ArrayStack {

    /*默认初始大小*/
    private final int DEFAULT_SIZE = 10;
    private Object[] elementArray;
    private int usedSize;

    public ArrayStack() {
        elementArray = new Object[DEFAULT_SIZE];
    }

    /**
     * 压栈
     *
     * @param e
     */
    public E push(E e) {
        if (isFull()) {
            elementArray = Arrays.copyOf(elementArray, 2 * elementArray.length);
        }
        elementArray[usedSize] = e;
        usedSize++;
        return e;
    }

    /**
     * 弹栈
     *
     * @return
     */
    public E pop() {
        if (usedSize == 0) throw new EmptyStackException();
        E topE = (E) elementArray[usedSize - 1];
        usedSize--;
        elementArray[usedSize] = null;
        return topE;
    }

    /**
     * 获取栈顶元素
     */
    public E peek() {
        if (usedSize == 0) throw new EmptyStackException();
        return (E) elementArray[usedSize - 1];
    }

    /**
     * 数组是否已满
     *
     * @return
     */
    private boolean isFull() {
        return usedSize == elementArray.length;
    }

    /**
     * 栈中是否有元素
     *
     * @return
     */
    public boolean isEmpty() {
        return usedSize == 0;
    }

}

(2)方式二:链表的方式实现:

public class LinkStack {

    private Node head;

    /**
     * 压栈
     *
     * @param e
     * @return
     */
    public E push(E e) {
        Node node = new Node<>(e);
        node.next = head;
        head = node;
        return e;
    }

    /**
     * 弹栈
     *
     * @return
     */
    public E pop() {
        if (head == null) throw new EmptyStackException();
        E val = head.val;
        Node oldHead = head;
        head = head.next;
        oldHead.next = null;
        return val;
    }

    /**
     * 获取栈顶元素
     *
     * @return
     */
    public E peek() {
        if (head == null) throw new EmptyStackException();
        return head.val;
    }

    /**
     * 获取栈中元素的个数
     *
     * @return
     */
    public int size() {
        if (head == null) return 0;
        Node temp = head;
        int size = 0;
        while (temp != null) {
            size++;
            temp = temp.next;
        }
        return size;
    }

    /**
     * 栈中是否有元素
     *
     * @return
     */
    public boolean isEmpty() {
        return head == null;
    }

    public static class Node {
        public E val;
        public Node next;

        public Node(E val) {
            this.val = val;
        }
    }
}

你可能感兴趣的:(总结知识点,LinkedList,集合,Java,Android)