教你如何使用Java手写一个基于链表的队列
在上一篇博客【教你如何使用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手写一个基于链表的队列的更多相关文章
- 教你如何使用Java手写一个基于数组实现的队列
一.概述 队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表.在具体应用中通常用链表或者数组来实现.队列只允许在后端(称为rear)进行插入操作,在 ...
- 手把手教你手写一个最简单的 Spring Boot Starter
欢迎关注微信公众号:「Java之言」技术文章持续更新,请持续关注...... 第一时间学习最新技术文章 领取最新技术学习资料视频 最新互联网资讯和面试经验 何为 Starter ? 想必大家都使用过 ...
- 【spring】-- 手写一个最简单的IOC框架
1.什么是springIOC IOC就是把每一个bean(实体类)与bean(实体了)之间的关系交给第三方容器进行管理. 如果我们手写一个最最简单的IOC,最终效果是怎样呢? xml配置: <b ...
- 搞定redis面试--Redis的过期策略?手写一个LRU?
1 面试题 Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2 考点分析 1)我往redis里写的数据怎么没了? 我们生产环境的redis怎么经常会丢掉一些数据?写进去了 ...
- 利用SpringBoot+Logback手写一个简单的链路追踪
目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...
- java 手写 jvm高性能缓存
java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...
- 看年薪50W的架构师如何手写一个SpringMVC框架
前言 做 Java Web 开发的你,一定听说过SpringMVC的大名,作为现在运用最广泛的Java框架,它到目前为止依然保持着强大的活力和广泛的用户群. 本文介绍如何用eclipse一步一步搭建S ...
- 摊牌了!我要手写一个“Spring Boot”
目前的话,已经把 Spring MVC 相关常用的注解比如@GetMapping .@PostMapping .@PathVariable 写完了.我也已经将项目开源出来了,地址:https://gi ...
- 手写一个最迷你的Web服务器
今天我们就仿照Tomcat服务器来手写一个最简单最迷你版的web服务器,仅供学习交流. 1. 在你windows系统盘的F盘下,创建一个文件夹webroot,用来存放前端代码. 2. 代码介绍: ( ...
随机推荐
- element.dispatchEvent is not a function的解决
Firebug中的出错提示: element.dispatchEvent is not a function element.dispatchEvent(event); prototype.js (第 ...
- Ocelot中文文档-不支持
Ocelot不支持一下几点... 分块编码 - Ocelot将始终获取body大小并返回Content-Length头. 如果这不适合你的场景,只能表示抱歉! 转发host头 - 您发给Ocelot的 ...
- 在基于debian的deepin或者Ubuntu上双等号“==”和双中括号“[[]]”不能使用的真相
使用的deepin-linux,今天写shell脚本的时候,忽然发现 sh test.sh 会报错[[: not found ,双等号和双中括号都不能使用了,很郁闷,后来探索发现,sh其实是dash的 ...
- windows下注册表的操作
原博:https://blog.csdn.net/denghubu/article/details/5765921 1. 注册表简介 注册表是为Windows NT和Windows95中所 ...
- python logging method 02
基本用法 下面的代码展示了logging最基本的用法. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ...
- 洛谷 P1462 解题报告
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- springboot: thymeleaf 使用详解
springboot:thymeleaf,这篇文章将更加全面详细的介绍thymeleaf的使用.thymeleaf 是新一代的模板引擎,在spring4.0中推荐使用thymeleaf来做前端模版引擎 ...
- unity3d入门教程
2010年Unity3D游戏引擎进入人们的视野,它操作简单.易学.灵活,逐步被各类平台厂商运用到新作品中,产生了全球游戏开发商.个人使用Unity3D的热潮.而在国内,根据权威部门统计,50%的Uni ...
- 浅谈通信网络(三)——TCP/IP协议
简介 Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议.In ...
- 数据库SQL语句中 查询选修了全部课程的学生的学号和姓名
一.SQL语言查询选修了全部课程的学生的学号和姓名. 两种解决途径: 第一种: 我们可以表示为在SC表中某个学生选修的课程数等于C表中课程总数.相应的SQL语言如下: select S#,SNAME ...