LInkedList实现队列(Queue)和堆栈(Stack)

LinkedList是用双向链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。

底层是一个双向链表,链表擅长插入和删除操作,队列和栈最常用的2种操作都设计到插入和删除image
通过LinkedList继承关系图我们可以发现,LinedList实现了Queue接口,Queue接口与List、Set同一级别,都是继承了Collection接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。

Queue:一个队列就是一个先进先出(FIFO)的数据结构

1.首先是队列,即FIFO模型。

public class Main  {
    
    
    public static void main(String[] args) {
    
    

        LinkedList<String> queue = new LinkedList<String>();
        queue.offer("one");
        queue.offer("two");
        queue.offer("three");
        while (queue.peek() != null) 
            System.out.println(queue.poll());
    }
}

输出:

one
two
three

队列中的方法

image

  • add() 会在容量不够时抛出异常:IllegalStateException; offer()则不会,只返回false
  • element() 会在没元素时抛出异常:NoSuchElementException; peek()返回null;
  • remove() 会在没元素时抛出异常:NoSuchElementException; poll()返回null;
  • offer() 将指定的元素插入此队列(如果立即可行且不会违反容量限制),此方法通常要优于 add(E)

通常使用offer(),peek(),poll()方法进行操作,可以避免异常,符合队列的数据结构。

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

区别

offer,add 区别:

一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。

这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。

poll,remove 区别:

remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似, 但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。

peek,element 区别:

element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null。

2.然后在来看下栈,FILO模型。这里不是stack接口,java把它封装Deque接口里。

堆栈方法 等效 Deque 方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()
public class Main  {
    
    
    public static void main(String[] args) {
    
    

        Deque deque = new LinkedList<String>();
        deque.push("one");
        deque.push("two");
        deque.push("three");
        while (deque.peek() != null) 
             System.out.println(deque.pop());
    }
}

输出:

three
two
one

通过上面可以看出栈和堆还是有区别的:

  1. -:栈是后进先出,使用的关键词是:pop,push和peek

  2. :堆是先进先出,使用的关键词是:enqueue、dequeue和peek

3.再来看一下LinekedList

队列 FIFO 先进先出

public class Main {
    
    
    public static void main(String[] args) {
    
    
        LinkedList queue = new LinkedList();
        queue.add(1);
        queue.add(2);
        queue.add(3);

        //FIFO 先进先出 通过removeFirst()验证一下
        while (!queue.isEmpty())
            System.out.println(queue.removeFirst());
    }
}

输出:

1
2
3

我们可以发现输出的结果和添加的顺序是一致的,添加头部添加,取从头部去取,所以呢 “先进先出”

队列是双端的 ,可以把它当作栈区使用 FILO 先进后出

public class Main {
    
    
    public static void main(String[] args) {
    
    
        LinkedList queue = new LinkedList();
        queue.add(1);
        queue.add(2);
        queue.add(3);

        // 当作栈区使用 FILO 先进先出
        while (!queue.isEmpty())
            System.out.println(queue.removeLast());
    }
}

输出:

3
2
1

发现先添加的元素 最后输出,“先进后出”

猜你喜欢

转载自blog.csdn.net/weixin_47815882/article/details/108684188