0    课程地址

https://coding.imooc.com/lesson/207.html#mid=13450

 

1    重点关注

1.1    代码草图解析

 

 

 

1.2    使用链表实现队列代码解析

见3.1

 

1.3    链表生成的队列和动态数组生成的循环队列 性能比较 代码解析

见3.3

 

2    课程内容


3    Coding

3.1    使用链表实现栈代码解析 关键代码

 

public LinkedListQueue(){
        size = 0;
        head = null;
        tail = null;
    }

    /**
     * 链表尾进行入队
     * @author weidoudou
     * @date 2022/10/30 18:09
     * @param e 请添加参数描述
     * @return void
     **/
    @Override
    public void enQueue(E e) {

        if(tail==null){
            tail = new Node(e);
            head = tail;
        }else{
            tail.next = new Node(e);
            tail = tail.next;
        }
        size++;
    }

    /**
     * 链表首进行出队,(因为相比较而言链表尾不容易出队,链表尾出队的话,倒数第二个node无法取到)
     * @author weidoudou
     * @date 2022/10/30 18:02
     * @return E
     **/
    @Override
    public E deQueue() {
        if(isEmpty()){
            throw new IllegalArgumentException("队列为空,无法出队");
        }
        Node retNode = head;
        head = head.next;//注意这里用head.next 而不要用retNode.next
        retNode.next = null;

        //这里遗漏了,如果head变成null了,说明链表已经为空了,需要把tail也置为空
        if(head==null){
            tail = null;
        }
        size--;
        return retNode.e;

    }

    @Override
    public E getFront() {
        if(size==0){
            throw new IllegalArgumentException("队列为空,无法查看队列顶元素");
        }
        return head.e;
    }

 

 

3.2    使用链表实现栈代码解析 全量代码

  • 实现类:

 

package com.company;

/**
 *  由于链表只能在一端进行操作,而队列可以在两端操作,先进先出,所以定义栈顶head和栈底tail比较方便O(1)操作
 * @author weidoudou
 * @date 2022/10/30 16:43
 * @return null
 **/
public class LinkedListQueue<E> implements Queue<E>{

    /**
     * 1  内部类node
     * @author weidoudou
     * @date 2022/10/28 7:59
     * @return null
     **/
    private class Node{
        //Node 只有两个属性,下一个节点和本节点存储的元素
        private E e;
        private Node next;

        /**
         * 通用调用node方法
         * @author weidoudou
         * @date 2022/10/28 8:17
         * @param e 请添加参数描述
         * @param  next 请添加参数描述
         * @return null
         **/
        public Node(E e,Node next){
            this.e = e;
            this.next = next;
        }

        /**
         * node 无参构造
         * @author weidoudou
         * @date 2022/10/28 8:15
         * @return null
         **/
        public Node(){
            this(null,null);
        }

        /**
         * node 有参构造
         * @author weidoudou
         * @date 2022/10/28 8:16
         * @param e 请添加参数描述
         * @return null
         **/
        public Node(E e){
            this(e,null);
        }


        @Override
        public String toString() {
            return e.toString();
        }
    }

    private int size;
    private Node head,tail;

    public LinkedListQueue(){
        size = 0;
        head = null;
        tail = null;
    }

    /**
     * 链表尾进行入队
     * @author weidoudou
     * @date 2022/10/30 18:09
     * @param e 请添加参数描述
     * @return void
     **/
    @Override
    public void enQueue(E e) {

        if(tail==null){
            tail = new Node(e);
            head = tail;
        }else{
            tail.next = new Node(e);
            tail = tail.next;
        }
        size++;
    }

    /**
     * 链表首进行出队,(因为相比较而言链表尾不容易出队,链表尾出队的话,倒数第二个node无法取到)
     * @author weidoudou
     * @date 2022/10/30 18:02
     * @return E
     **/
    @Override
    public E deQueue() {
        if(isEmpty()){
            throw new IllegalArgumentException("队列为空,无法出队");
        }
        Node retNode = head;
        head = head.next;//注意这里用head.next 而不要用retNode.next
        retNode.next = null;

        //这里遗漏了,如果head变成null了,说明链表已经为空了,需要把tail也置为空
        if(head==null){
            tail = null;
        }
        size--;
        return retNode.e;

    }

    @Override
    public E getFront() {
        if(size==0){
            throw new IllegalArgumentException("队列为空,无法查看队列顶元素");
        }
        return head.e;
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size==0;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("LinkedListQueue:front ");

        Node cur = head;
        while (cur!=null){
            sb.append(cur+"->");
            cur=cur.next;
        }
        sb.append("Null tail");
        return sb.toString();
    }
}

 

 

 

  • 接口:

 

package com.company;

/**
 * 队列接口
 * @author weidoudou
 * @date 2022/10/23 11:10
 * @return null
 **/
public interface Queue<E> {

    /**
     * 循环队列入队 队尾插入元素
     * @author weidoudou
     * @date 2022/10/23 11:10
     * @param e 请添加参数描述
     * @return void
     **/
    void enQueue(E e);

    /**
     * 循环队列出队 队首删除元素
     * @author weidoudou
     * @date 2022/10/23 11:11
     * @return E
     **/
    E deQueue();

    /**
     * 队首展示元素
     * @author weidoudou
     * @date 2022/10/23 11:11
     * @return E
     **/
    E getFront();

    /**
     * 获取size
     * @author weidoudou
     * @date 2022/10/23 11:12
     * @return int
     **/
    int getSize();

    /**
     * 是否为空
     * @author weidoudou
     * @date 2022/10/23 11:12
     * @return boolean
     **/
    boolean isEmpty();

}

 

 

 

  • 测试类:

 

public static void main(String[] args) {
        Queue<Integer> queue = new LinkedListQueue<>();
        for(int i = 0;i<10 ;i++){
            queue.enQueue(i);
            System.out.println(queue);

            if(i%3==0){
                queue.deQueue();
                System.out.println(queue);
            }
        }
    }

 

 

 

  • 测试结果:

 

LinkedListQueue:front 0->Null tail
LinkedListQueue:front Null tail
LinkedListQueue:front 1->Null tail
LinkedListQueue:front 1->2->Null tail
LinkedListQueue:front 1->2->3->Null tail
LinkedListQueue:front 2->3->Null tail
LinkedListQueue:front 2->3->4->Null tail
LinkedListQueue:front 2->3->4->5->Null tail
LinkedListQueue:front 2->3->4->5->6->Null tail
LinkedListQueue:front 3->4->5->6->Null tail
LinkedListQueue:front 3->4->5->6->7->Null tail
LinkedListQueue:front 3->4->5->6->7->8->Null tail
LinkedListQueue:front 3->4->5->6->7->8->9->Null tail
LinkedListQueue:front 4->5->6->7->8->9->Null tail

Process finished with exit code 0

 

 

3.3    链表生成的队列和动态数组生成的循环队列 性能比较 代码解析

  • 测试类:
    public static void main(String[] args) {

        int count = 1000000;
        //循环数组队列
        Queue<Integer> loopQueue = new LoopQueue<>();
        //数组队列
        Queue<Integer> linkedListQueue = new LinkedListQueue<>();

        double time1 = getLinkedListAndArray(linkedListQueue,count);
        System.out.println("linkedListQueue time1==="+time1);
        double time2 = getLinkedListAndArray(loopQueue,count);
        System.out.println("loopQueue  time2==="+time2);

    }

 

  • 测试结果:

 

 

linkedListQueue time1===0.0274841
loopQueue  time2===0.0528964

Process finished with exit code 0

 

posted on 2022-10-30 19:24  菜鸟乙  阅读(77)  评论(0编辑  收藏  举报

目录导航