java链表应用--基于链表实现队列详解(尾指针操作)

 更新时间:2020年03月17日 12:13:09   作者:WFaceBoss  
这篇文章主要介绍了java链表应用--基于链表实现队列,结合实例形式分析了java基于链表实现队列尾指针相关操作使用技巧,需要的朋友可以参考下

本文实例讲述了java基于链表实现队列。分享给大家供大家参考,具体如下:

在开始栈的实现之前,我们再来看看关于链表的只在头部进行的增加、删除、查找操作,时间复杂度均为O(1)。

一、链表改进分析

对于队列这种数据结构,需要在线性结构的一端插入元素,另外一端删除元素。因此此时基于链表来实现队列,则有一端的时间复杂度为O(n)。因此我们不能使用之前已经实现的链表结构,我们需要改进我们的链表。思路如下:

1.参考在链表头部删除、增加元素的时间复杂度为O(1)的思路,我们在链表的尾部设立一个Node型的变量tail来记录链表的尾部在哪,此时再head端和tail端添加元素都是及其简单的,在head端删除元素也是及其简单的,但对于在tail端删除元素时,是无法在时间复杂度为O(1)的情况进行的,也就是从tail端删除元素时不容易的。

2.只在头部head删除元素(队首),在尾部tail端添加元素(队尾)。

3.由于在基于链表实现队列时不涉及到操作链表中间元素,此时我们改进的链表中,不在使用虚拟头节,因此也就可能造成在没有虚拟头节点的情况下,链表为空。

二、链表改进代码

前言,在写本小节之前,我们已经实现了一个基于静态数组的队列,转到查看。此处我们实现基于链表的队列。

在实现基于静态数组的队列的时候,我们已经新建了一个package,此时我们在该package下新建一个LinkedListQueue类,用来实现Queue接口,目录结构为:

1.Queue接口代码

package Queue;

public interface Queue<E> {
  //获取队列中元素个数
  int getSize();

  //队列中元素是否为空
  boolean isEmpty();

  //入队列
  void enqueue(E e);

  //出队列
  public E dequeue();

  //获取队首元素
  public E getFront();
}

2.LinkedListQueue类

package Queue;

public class LinkedListQueue<E> implements Queue<E> {

  //将Node节点设计成私有的类中类
  private class Node<E> {
    public E e;
    public Node next;

    //两个参数的构造函数
    public Node(E e, Node next) {
      this.e = e;
      this.next = next;
    }

    //一个参数的构造函数
    public Node(E e) {
      this.e = e;
      this.next = null;
    }

    //无参构造函数
    public Node() {
      this(null, null);
    }

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

  private Node<E> head, tail;

  private int size;


  //显示初始化
  public LinkedListQueue() {
    head = null;
    tail = null;
    size = 0;
  }

  //获取队列中节点个数
  @Override
  public int getSize() {
    return size;
  }

  //队列中是否为空
  @Override
  public boolean isEmpty() {
    return size == 0;
  }

  //链表尾部进队操作
  @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++;
  }

  //链表头部出队操作
  @Override
  public E dequeue() {
    if (isEmpty()) {
      throw new IllegalArgumentException("链表为空");
    }

    Node<E> retNode = head;
    head = head.next;
    retNode.next = null;
    if (head == null) {//当链表只有一个元素时
      tail = null;
    }

    size--;
    return retNode.e;
  }

  //获取队首元素
  @Override
  public E getFront() {
    if (isEmpty()) {
      throw new IllegalArgumentException("链表为空");
    }
    return head.e;
  }


  //为了便于测试,重写object类toString()方法
  @Override
  public String toString() {
    StringBuilder res = new StringBuilder();
    res.append("Queue: front ");
    Node<E> cur = head;
    while (cur != null) {
      res.append(cur + "->");
      cur = cur.next;
    }
    res.append("NULL tail");
    return res.toString();
  }


}

3.为了便于测试,在LinkedListQueue类中添加一个main函数

 //测试用例
  public static void main(String[] args) {
    LinkedListQueue<Integer> queue = new LinkedListQueue<Integer>();
    for (int i = 0; i < 10; i++) {
      queue.enqueue(i);
      System.out.println(queue);

      if (i % 3 == 2) {//每添加3个元素出队列一个
        queue.dequeue();
        System.out.println(queue);
      }

    }

  }

4.结果为

结果分析:每进队3个元素出队列一个。

关于本小节,若您觉得还行、还过得去,记得给个推荐哦~,谢谢!!

本节源码 https://github.com/FelixBin/dataStructure/blob/master/src/Queue/LinkedListQueue.java

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

相关文章

  • druid执行SQL出现错误但不影响返回结果的问题及解决

    druid执行SQL出现错误但不影响返回结果的问题及解决

    这篇文章主要介绍了druid执行SQL出现错误但不影响返回结果的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 通过Spring Boot配置动态数据源访问多个数据库的实现代码

    通过Spring Boot配置动态数据源访问多个数据库的实现代码

    这篇文章主要介绍了通过Spring Boot配置动态数据源访问多个数据库的实现代码,需要的朋友可以参考下
    2018-03-03
  • java IO流 之 输出流 OutputString()的使用

    java IO流 之 输出流 OutputString()的使用

    这篇文章主要介绍了java IO流 之 输出流 OutputString()的使用的相关资料,需要的朋友可以参考下
    2016-12-12
  • spring依赖注入深入理解

    spring依赖注入深入理解

    这篇文章主要介绍了spring依赖注入深入理解,列举了最常见的注入方式,有感兴趣的同学可以研究下
    2021-03-03
  • 解读JSONArray删除元素的两种方式

    解读JSONArray删除元素的两种方式

    这篇文章主要介绍了解读JSONArray删除元素的两种方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • JavaWeb中的Response常用方法解析

    JavaWeb中的Response常用方法解析

    这篇文章主要介绍了JavaWeb中的Response常用方法解析,response对象是用来对客户端进行响应的当浏览器发出请求时, Web容器创建一个ServletRequest对象封装请求信息,一个ServletResponse对象封装响应信息,对象作为Servlet的service()方法中的参数,需要的朋友可以参考下
    2023-11-11
  • Java实现的n阶曲线拟合功能示例

    Java实现的n阶曲线拟合功能示例

    这篇文章主要介绍了Java实现的n阶曲线拟合功能,结合实例形式分析了Java基于矩阵的多项式曲线拟合相关操作技巧,需要的朋友可以参考下
    2018-01-01
  • SpringBoot详解整合MyBatis过程中可能遇到的问题

    SpringBoot详解整合MyBatis过程中可能遇到的问题

    因为Spring Boot框架开发的便利性,所以实现Spring Boot与数据访问层框架(例如MyBatis)的整合非常简单,主要是引入对应的依赖启动器,并进行数据库相关参数设置即可
    2022-07-07
  • Java踩坑记录之BigDecimal类

    Java踩坑记录之BigDecimal类

    这篇文章主要给大家介绍了关于Java踩坑记录之BigDecimal类的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Java实现8种排序算法的示例代码

    Java实现8种排序算法的示例代码

    这篇文章主要介绍了8种JAVA实现排序算法的示例代码,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06

最新评论