将双向链表做简单的改造,即可实现一个FIFO(First Input First Out)队列,

该队列只在头节点出队,尾节点入队。

一般来说定义节点类只需一个后驱节点next即可。

这里保留pre节点,模拟一个已经入队的节点,如果需要取消,这样pre节点就是一个优势。

定义节点类:

/**
* 队列元素
*/
public class Node
{
private int data;//数据域
private Node pre;//指向上一个节点
private Node next;//指向下一个节点 public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getPre() {
return pre;
}
public void setPre(Node pre) {
this.pre = pre;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
} //构造函数
public Node(int data, Node pre, Node next){
this.data = data;
this.pre = pre;
this.next = next;
}
public Node(int data){
this(data,null,null);
}
public Node(){
this(0,null,null);
} }

队列实现:

 1 /**
2 * Java双向链表实现队列(FIFO)
3 * Author:hangwei
4 * 2022/11
5 */
6 public class DQueue {
7 private Node head;
8 private Node tail;
9 private int size;
10 public Node getHead() {
11 return head;
12 }
13 public Node getTail() {
14 return tail;
15 }
16 public DQueue(){
17 tail = head = null;
18 size = 0;
19 }
20
21 //尾部入队
22 public void add(Node target){
23 if(target == null)
24 return;
25 if (size == 0) {
26 target.setPre(target);
27 target.setNext(target);
28 tail = head = target;
29 } else{
30 tail.setNext(target);//尾节点的下一个节点是新节点
31 target.setPre(tail);//新节点的上一个节点是尾节点
32 //标记新的尾节点
33 tail = target;
34 }
35 size++;
36 }
37
38 //头节点出队or取消某个已入队节点
39 public void romove(Node target){
40 if(size == 0){
41 System.out.println("null linked list ,can not delete.");
42 return;
43 }
44 else if(size == 1){
45 head = tail = null;
46 }
47 else if(target == null || target.equals(head)) {//target为空或头节点,则头出队
48 head = head.getNext();
49 head.setPre(null);
50 }
51 else {//移除队列中指定的元素
52 target.getPre().setNext(target.getNext());
53 target.getNext().setPre(target.getPre());
54 if(target.equals(tail))//如果出队是尾节点
55 tail=target.getPre();//标记新的尾节点
56 }
57 size--;
58 }
59
60 //打印队列
61 public void print(){
62 Node node = new Node();
63 node = head;
64 while (node.getNext() != head && node.getNext() != null){//遍历
65 System.out.print(node.getData());
66 System.out.print("<->");
67 node = node.getNext();
68 }
69 System.out.print(node.getData());//补充打印循环体的最后一个节点
70 System.out.println();
71 }
72 }

测试:

public class Main {
public static void main(String[] args) {
DQueue dq = new DQueue();
dq.add(new Node(111));
dq.add(new Node(222));
dq.add(new Node(333));
dq.add(new Node(444));
dq.add(new Node(555));
dq.print();
dq.romove(null);
dq.print();
dq.romove(dq.getHead().getNext());
dq.print();
}
}

执行结果:

*重点:使用双指针链表实现队列,可以很方便的移除队列中某个不需要的元素。

Java双向链表实现队列的更多相关文章

  1. Java多线程 阻塞队列和并发集合

    转载:大关的博客 Java多线程 阻塞队列和并发集合 本章主要探讨在多线程程序中与集合相关的内容.在多线程程序中,如果使用普通集合往往会造成数据错误,甚至造成程序崩溃.Java为多线程专门提供了特有的 ...

  2. Java 中的队列 Queue

    一.队列的定义 我们都知道队列(Queue)是一种先进先出(FIFO)的数据结构,Java中定义了java.util.Queue接口用来表示队列.Java中的Queue与List.Set属于同一个级别 ...

  3. java实现链队列

    java实现链队列的类代码: package linkqueue; public class LinkQueue { class Element { Object elem; Element next ...

  4. Java服务器端消息队列实战

    服务端口监听--报文接收--报文解码--业务处理--报文编码--写回客户端 从服务端与客户端成功握手并产生一个socket后,为了提高吞吐能力,接下来的事情就可以交给多线程去处理. 为了对接入的请求做 ...

  5. 使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点?

    我感觉很多项目使用java或者c的多线程库+线程安全的queue数据结构基本上可以实现goroutine+channel开发能达到的需求,所以请问一下为什么说golang更适合并发服务端的开发呢?使用 ...

  6. java中有界队列的饱和策略(reject policy)

    文章目录 AbortPolicy DiscardPolicy DiscardOldestPolicy CallerRunsPolicy 使用Semaphore java中有界队列的饱和策略(rejec ...

  7. Java集合--阻塞队列及各种实现的解析

    阻塞队列(Blocking Queue) 一.队列的定义 说的阻塞队列,就先了解下什么是队列,队列也是一种特殊的线性表结构,在线性表的基础上加了一条限制:那就是一端入队列,一端出队列,且需要遵循FIF ...

  8. Java:阻塞队列

    Java:阻塞队列 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. 概述 概念 队列 队列就可以想成是一个数组,从一头进入,一头出去,排队买饭 阻塞队列 B ...

  9. Java并发--阻塞队列

    在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程 ...

  10. java代码实现队列的优化

    package com.voole.queun; /** * @Decription 队列 * @author TMAC-J * */ public class Queun { /** * 初始化队列 ...

随机推荐

  1. DHCP分配IP的流程

    1.DHCP客户端以广播的形式发送DHCP Discover报文 2.所有的DHCP服务端都可以接收到这个DHCP Discover报文,所有的DHCP服务端都会给出响应,向DCHP客户端发送一个DH ...

  2. C语言声明与定义的区别

    转自:https://blog.csdn.net/gatieme/article/details/50640424 C++程序通常由许多文件组成,为了让多个文件访问相同的变量,C++区分了声明和定义. ...

  3. .NET实验三

    实验名称:实验三 Windows 应用程序开发 一. 实验目的 1. 掌握窗口控件的使用方法: 2. 掌握 Windows 的编程基础. 二. 实验要求   根据要求,编写 C#程序,并将程序代码和运 ...

  4. 安装DevExpress VCL,使用时报错 某单元文件找不到的解决办法

    1.新建一个工程做为测试 2.点击projecct-->options 3. 4. 5.在上4图上的红框内加入packages文件 dxCoreRS27;dxGDIPlusRS27;dxComn ...

  5. NFS存储安装配置

    一.NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种, 它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS的客 户 ...

  6. MYSQL 变更账号密码

    #1 首先找到Mysql[安装的路径],切换到对应的bin目录,例如安装在D盘 C:User\Administrator> d:(输入盘符回车) D:\> cd D:\MySQL\MySQ ...

  7. Java笔记第十三弹

    函数式接口 有且仅有一个抽象方法的接口 适用于Lambda使用的接口 @FunctionalInterface//表示函数式接口 函数式接口作为方法的参数 public class Main{ pub ...

  8. Android笔记--图形控制

    图形Drawable 形状图形(其定义文件是以shape标签为根节点的XML描述文件,支持四种类型的形状) 具体实现: 在shape标签里面,solid指定填充的颜色,stroke指定边框颜色,cor ...

  9. Java数据脱敏(手机号|邮箱号|身份证号|银行卡号)

    参考博客:https://blog.csdn.net/ywb201314/article/details/107762279

  10. 自己动手从零写桌面操作系统GrapeOS系列教程——14.屏幕显示原理与文本模式

    学习操作系统原理最好的方法是自己写一个简单的操作系统. 一.屏幕显示原理 电脑显示器屏幕是由很多很小的像素组成的.每个像素就像是一个小灯泡,在屏幕上一排一排的整齐排列着.只要能控制每个像素的颜色就能显 ...