手写由链表设计的简易队列

好多人都觉得为什么要自己写这样的数据结构,变成里面不是有吗?为什么要去写,有这个疑问,其实这个疑问这我的脑海中也存在了很长一段时间,本人是学习java编程的,直接看java的集合框架不行吗?这个时候如果你的水平到了还好。如果没有,你会发现你根本就理解不了编程语言里面数据结构,看了就忘掉了,也理解不了,学习了半个月编程里面的集合发现学不会,还要抱怨怎么可以这样,看了半个月都没有看懂,于是就放弃了。如果让我来分析缘由,那就是市面上已经发布的编程语言里面的数据结构(集合框架)都是王者水平(巅峰王者)的人写的,这样厉害的人写出的东西,你一个没有啥基础的编程人员(按照游戏段位排序:青铜),几天几个月就整的明明白白,如果这样都能会,只有一种可能,你是天才,不是普通人。
所以基于这样的分析,我们学习就是要先从没有进数据结构的大门到变得更够秀(进军白银段位以致更高的水平),所以简易版的练习过程是在必行,脚踏实地,方是走过漫漫长路的捷径之路,于此,便有了一些列的数据结构的简易版,今天分析由链表设计的队列。

简单的代码搭建及思维逻辑分析

public class LinkedListQueue<E> implements QueueDemo<E>{
    /**
     * 节点类
     */
    private class Node {
        public E e;
        public Node next;

        public Node(E e, Node next) {
            this.e = e;
            this.next = next;
        }
        public Node(E e) {
            this(e, null);
        }
        public Node() {
            this(null, null);
        }
        @Override
        public String toString() {
            return e.toString();
        }
    }
    private Node head,tail;
    private int size;
    public LinkedListQueue() {
        this.head=null;
        this.tail=null;
        this.size=0;
    }
    @Override
    public int getSize() {
        return size;
    }
    @Override
    public boolean isEmpty() {
        return size==0;
    }
}

内部节点类为了存储队列引用而设计, 由于队列是头出尾进,所以需要设计head、tail头尾节点,用于管理出队和入队,size属性由于记录队列实时大小;而设计的出队和入队进行重点分析。

入队操作代码分析

代码如下:

    @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++;
    }

1、入队操作时在队尾进行,所以有tail进行管理,当队列中一个节点都没有的时候(tail=null),初始tail和head都为null,当有值进行入队的时候,创建新节点node赋值给tail,再将tail(尾)的引用赋值给head(头),size+1(size++); 2、当已经存在第一个节点,向后添加节点,代码如下:

 tail.next=new Node(e);
 tail=tail.next;

思维逻辑图如下:
在这里插入图片描述
3、最后将size++;

出队操作代码分析

代码如下:

  @Override
    public E dequeue() {
        if (isEmpty())
            throw new IllegalArgumentException("cannot ");
        Node retNode=head;
        head=head.next;
        retNode.next=null;
        if (head==null)
            tail=null;
        size--;
        return retNode.e;
    }

1、想要出队首先要查看队列里是否有元素,不为空;2、上面刚刚论述了入队需要tail来管理,那么出队现在就需要head(头)来管理:队列(尾进头出);代码分析:头元素赋值给零时引用retNode(也就是要移除的节点),之后head节点引用安全的指向零时引用之后,将head节点的下个节点作为head,即head=head.next,这个时候就需要将原来的节点Node与目前的head引用关系断开,所以将 retNode.next=null赋值为null.
在这里插入图片描述
之后就是出队的过程中,head为null了,代表队列已经为空了;代码如下:

    if (head==null)
            tail=null;

由于正常情况下,出队一直没有对tail进行引用管理,但是当队列里面只有一个节点,出队以后,head这个时候已经为null了,但是tail还是还是指向原来出队节点的引用,所以,这个时候需要将tail也设置为null.
3、之后做完上述操作以后进行size-1(size–),并把retNode.e的值返回回去。

查看头元素方法

队列有进队和出队,当然还有查询队首元素的方法。
1、判断队列是否为空;2、将head.e的值返回

    @Override
    public E getFront() {
        if (isEmpty())
            throw new IllegalArgumentException("Queue is empty. ");
        return head.e;
    }

写博不易,关注博客了解更多原创详情。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值