在上一篇博客【教你如何使用Java手写一个基于数组的队列】中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章。那么,现在就直接进入主题吧。

  这篇博客主要讲解的是如何使用单链表实现一个简单版的队列。单向链表队列是属于非循环队列,同时队列的长度是不受限制的,也就是说添加数据的速度比拉取数据的速度快时,队列的长度是无限增长的。单链队列其本质就是一个链表,只不过是在获取或添加数据的时候跟普通的链表有所区别,队列在获取数据的同时也将该节点删除,并且每次获取数据都是从表头获取,普通链表可以获取任意节点的数据;队列在增加数据时总是添加到链表的尾部,而普通的链表则是可以在链表的任意地方插入一个节点。

  一、队列数据结构

  该队列的结构够多个节点构成,每个节点都有一个指向下一个节点的指针,使得所有的节点都能够相连,形成一个链表。具体结构如下如:

  Java实现:

static class Node{
Object item;
Node next; public Node(Object item, Node next) {
this.item = item;
this.next = next;
}
}

  其实就创建一个静态内部类即可,类中item是用来存储数据的,next是指向下一个node节点,最后一个节点的next为空。

  二、属性

  head:链表表头,拉取或遍历数据都是从这里开始的。

  tail:链表表尾,每次添加数据都添加到tail的后面,变成新的tail

  size:队列长度

  //表头
private Node head;
//表尾
private Node tail;
//队列长度
private int size;

  三、添加数据

 public void offer(Object item){
Node n = new Node(item,null);
if (tail == null){
head = tail = n;
}else {
tail.next = n;
tail = n;
}
size++;
}

  用代码实现队列的添加操作看起是很简单的,无非就是将新节点添加到表尾,然后把新节点设置成新的表尾。

  四、拉取数据

public Object poll(){
if (head == null) return null;
Node h = head;
//将拉取的节点的下一个节点变成新的表头
head = head.next;
//把旧的表头的下一个节点指向设置为null,让gc回收
h.next = null;
//队列为空
if (head == null)
tail = null;
size--;
return h.item;
}

  

  五、查看数据

public Object peek(){
return head == null ? null : head.item;
}

  查看数据看的是表头的数据,但是跟poll方法的区别是该方法不会删除表头的数据。

  六、清空列表

public void clear(){
size = ;
Node h = head;
while (h != null){
Node temp = h.next;
h.next = null;
h = temp;
}
head = tail = null;
}

  

  七、基于数组的队列和链表的队列的区别

  1、前者是有边界的循环队列,后者则是没有边界的非循环队列。

  2、前者在添加数据时无需创建新对象,性能消耗相对较小,后者每次添加数据都需要创建新对象。

  3、后者每个节点都维护了一个链,所以所需内存也相对较大。

  4、如果添加速度大于拉取速度,前者在达到边界后可能会无法添加数据,后者则没有这个问题。

  八、完整代码

/**
* 基于链表实现的队列
*/
public class LinkQueue { //表头
private Node head;
//表尾
private Node tail;
//队列长度
private int size; public LinkQueue(){} public void offer(Object item){
Node n = new Node(item,null);
if (tail == null){
head = tail = n;
}else {
tail.next = n;
tail = n;
}
size++;
} public Object poll(){
if (head == null) return null;
Node h = head;
//将拉取的节点的下一个节点变成新的表头
head = head.next;
//把旧的表头的下一个节点指向设置为null,让gc回收
h.next = null;
//队列为空
if (head == null)
tail = null;
size--;
return h.item;
} public Object peek(){
return head == null ? null : head.item;
} public void clear(){
size = ;
Node h = head;
while (h != null){
Node temp = h.next;
h.next = null;
h = temp;
}
head = tail = null;
} public int size(){return size;} static class Node{
Object item;
Node next; public Node(Object item, Node next) {
this.item = item;
this.next = next;
}
} @Override
public String toString() {
if (size == ) return "{}";
StringBuilder builder = new StringBuilder(size + );
Node h = head;
builder.append("{");
while (h != null){
builder.append(h.item);
builder.append(", ");
h = h.next;
}
return builder.substring(,builder.length() -) + "}";
}
}

教你如何使用Java手写一个基于链表的队列的更多相关文章

  1. 教你如何使用Java手写一个基于数组实现的队列

    一.概述 队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表.在具体应用中通常用链表或者数组来实现.队列只允许在后端(称为rear)进行插入操作,在 ...

  2. 手把手教你手写一个最简单的 Spring Boot Starter

    欢迎关注微信公众号:「Java之言」技术文章持续更新,请持续关注...... 第一时间学习最新技术文章 领取最新技术学习资料视频 最新互联网资讯和面试经验 何为 Starter ? 想必大家都使用过 ...

  3. 【spring】-- 手写一个最简单的IOC框架

    1.什么是springIOC IOC就是把每一个bean(实体类)与bean(实体了)之间的关系交给第三方容器进行管理. 如果我们手写一个最最简单的IOC,最终效果是怎样呢? xml配置: <b ...

  4. 搞定redis面试--Redis的过期策略?手写一个LRU?

    1 面试题 Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2 考点分析 1)我往redis里写的数据怎么没了? 我们生产环境的redis怎么经常会丢掉一些数据?写进去了 ...

  5. 利用SpringBoot+Logback手写一个简单的链路追踪

    目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...

  6. java 手写 jvm高性能缓存

    java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...

  7. 看年薪50W的架构师如何手写一个SpringMVC框架

    前言 做 Java Web 开发的你,一定听说过SpringMVC的大名,作为现在运用最广泛的Java框架,它到目前为止依然保持着强大的活力和广泛的用户群. 本文介绍如何用eclipse一步一步搭建S ...

  8. 摊牌了!我要手写一个“Spring Boot”

    目前的话,已经把 Spring MVC 相关常用的注解比如@GetMapping .@PostMapping .@PathVariable 写完了.我也已经将项目开源出来了,地址:https://gi ...

  9. 手写一个最迷你的Web服务器

    今天我们就仿照Tomcat服务器来手写一个最简单最迷你版的web服务器,仅供学习交流. 1. 在你windows系统盘的F盘下,创建一个文件夹webroot,用来存放前端代码.  2. 代码介绍: ( ...

随机推荐

  1. 用sql获取一段时间内的数据

    我把我CSDN写的   搬来博客园了.. SELECT * FROM 表名 WHERE timestampdiff(MINUTE, SYSDATE(), send_time) <=60 AND ...

  2. Codeforces Round #479 (Div. 3) C. Less or Equal

    题目地址:http://codeforces.com/contest/977/problem/C 题解:给一串数组,是否找到一个数x,找到k个数字<=x,找到输出x,不能输出-1.例如第二组,要 ...

  3. mysql8绿色免安装win64版本(自带heidisql.exe客户端)应该兼容老版第三方工具。

    https://pan.baidu.com/s/1cvQ4AJX6rmqSpMhBQTPz4Q 如果缺c库,自己去找下. 使用方法:先执行initdb.bat初始化数据 如果要安装为服务:执行inst ...

  4. 拾人牙慧篇之———QQ微信的第三方登录实现

    一.写在前面 关于qq微信登录的原理之流我就不一一赘述了,对应的官网都有,在这里主要是展示我是怎么实现出来的,看了好几个博客,有的是直接复制官网的,有的不知道为什么实现不了.我只能保证我的这个是我实现 ...

  5. css那些事(一)

    一.内边框padding和外边框margin属性缩写 内外边框有四个属性:padding-top,padding-right,padding-bottom,padding-left;margin-to ...

  6. Python 内置的一些高效率函数用法

    1.  filter(function,sequence) 将sequence中的每个元素,依次传进function函数(可以自定义,返回的结果是True或者False)筛选,返回符合条件的元素,重组 ...

  7. Python--Seaborn绘图和可视化--基本语法

    博客地址:http://www.cnblogs.com/yudanqu/ Seaborn是对matplotlib的extend,是一个数据可视化库,提供更高级的API封装,在应用中更加的方便灵活.下面 ...

  8. python:Json模块dumps、loads、dump、load介绍

    由上篇文章(python3+requests:get/post请求)涉及到的json.dumps()扩展 1.json.dumps()用于将dict类型的数据转成str 备注:文件路径前面加上 r 是 ...

  9. Hessian基础入门案例

    Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...

  10. sql server 高可用故障转移(上)

    群集准备工作 个人电脑 内存12G,处理器 AMD A6-3650CPU主频2.6GHz 虚拟机 VMware Workstation 12 数据库  sql server 2008 r2 三台虚拟服 ...