队列的几种实现方式

2023-11-20

队列简介:

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

队列是一种最常用的数据结构,也是最重要的一种数据结构,这里介绍三种实现队列的方法:

1.基于链表来实现队列。

2.使用linkedList来实现队列。

3.使用两个栈来实现一个队列。

 

1.首先说第一种实现方式,基于链表来实现队列:

首先添加一个节点类,作为队列中的节点元素

public class Node {		//链表中的一个节点
	Node next = null;
	int data;
	//构造函数,用于添加链表时候使用
	public Node(int d) {
		this.data = d;
	};
}

再新建一个类作为我们的队列,在该类中实现队列的入队和出队以及求队列的长度和判断队列是否为空等方法

①.入队操作:

             首先通过函数参数传入要入队的数据,根据传入的参数,新增一个节点Node,在入队方法中判断该队列是否为空,若该队列为空(head==tail),则该入队的节点既是队头也是队尾。若队列不为空,则将尾节点tail的next指针指向该元素,然后将tail节点指向该节点。

public void put(Integer data) {
		Node newNode = new Node(data);		//构造一个新节点
		if(head == null && tail == null) {	//队列为空
			head = newNode;
			tail = newNode;
		}else {
			tail.next = newNode;
			tail = newNode;
		}
	}

②.出队操作:

若队列为空,则返回空。若队列不为空,则返回该队列的头结点,然后将头结点的下一个元素重新作为头节点

public Integer pop() {
		if(this.isEmpty()) {
			return null;
		}
		int data = head.data;
		head = head.next;
		return data;
	}

③.判断队列空和对列长度很简单,直接贴代码,不再多说。

public int size() {
		int count = 0;
		Node tmp = head;
		while(tmp != null) {
			count++;
			tmp = tmp.next;
		}
		return count;
	}

④.详细代码实现:

package com.wp.datastruct;

/**
 * 利用链表来实现队列
 * */
public class MyQueue<E> {
	Node head = null;		//队列头
	Node tail = null;		//队列尾
	
	/**
	 * 入队操作:
	 * 		若该队列尾空,则入队节点既是头结点也是尾节点
	 * 		若队列不为空,则先用tail节点的next指针指向该节点
	 * 		然后将tail节点指向该节点
	 * */
	public void put(Integer data) {
		Node newNode = new Node(data);		//构造一个新节点
		if(head == null && tail == null) {	//队列为空
			head = newNode;
			tail = newNode;
		}else {
			tail.next = newNode;
			tail = newNode;
		}
	}
	
	/**
	 * 判断队列是否为空:当头结点等于尾节点的时候该队列就为空
	 * */
	public boolean isEmpty() {
		return head == tail;
	}
	
	/**
	 * 出队操作:
	 * 		若队列为空,则返回null
	 * 		否则,返回队列的头结点,并将head节点指向下一个
	 * */
	public Integer pop() {
		if(this.isEmpty()) {
			return null;
		}
		int data = head.data;
		head = head.next;
		return data;
	}
	
	public int size() {
		int count = 0;
		Node tmp = head;
		while(tmp != null) {
			count++;
			tmp = tmp.next;
		}
		return count;
	}

}

2.使用linkedList来实现队列

该方法是使用java中的linkedList集合来实现一个队列,通过调用linkedList中的方法来实现队列的入队出队,判空等操作

首先new一个类来作为我们的队列,该类中包含两个属性,一个是size:用来统计该队列的长度,另一个是LinkedList对象,

代表我们的队列。

private LinkedList<E> list = new LinkedList<>();
	private int size = 0;						//用于统计队列的长度

①.入队操作:

应为linkedList集合中已经实现好了添加删除操作,在这里我们只需要简单的调用方法就可以实现队列的相关操作了,非常简单而且容易理解。

public synchronized void put(E data) {		//保证线程安全,实现同步操作
		list.add(data);
		size++;
	}

②.出队操作:

public synchronized E pop() {
		size--;
		return list.removeFirst();				//从头取出
	}

③.详细代码:

public class MyQueue2<E> {
	
	private LinkedList<E> list = new LinkedList<>();
	private int size = 0;						//用于统计队列的长度
	
	public synchronized void put(E data) {		//保证线程安全,实现同步操作
		list.add(data);
		size++;
	}
	
	public synchronized E pop() {
		size--;
		return list.removeFirst();				//从头取出
	}
	
	public synchronized int size() {
		return size;
	}
	
	public boolean isEmpty() {
		return size == 0;
	}	
	
}

 

3.使用两个栈来实现一个队列。

也可以使用两个实现好的栈来实现一个队列(这个问题可能面试笔试的时候回被问到)。

实现方法是:

创建两个栈s1,s2。入队的时候就只压栈到s1中。

出队分两种情况:1.当s2不为空的使用,就弹出栈顶元素作为出队元素。

                             2.当s2等于空,则先将s1中的元素全部弹出到s2中,再从s2中弹出栈顶元素作为出队元素。

 

①.入队:

	public synchronized void put(E data) {		//使用同步处理,保证线程安全
		s1.push(data);
	}

②.出队:

public synchronized E pop() {
		if(!s2.isEmpty()) {
			return s2.pop();
		}else {
			s2.push(s1.pop());
			return s2.pop();
		}
	}

③.详细代码实现:

package com.wp.datastruct;

import java.util.Stack;

/**
 * 利用两个栈来模拟队列操作
 * 入队操作就只是想栈s1中添加,
 * 出栈操作分为两部分:
 * 1.当s2中不为空的时候,就直接弹出s2中的栈顶数据
 * 2.当s2中为空的时候,就先把s1中的数据全部弹出到s2中然后将栈顶数据出栈
 * 
 * */
public class MyQueue3<E> {
	Stack<E> s1 = new Stack<>();
	Stack<E> s2 = new Stack<>();
	
	public synchronized void put(E data) {		//使用同步处理,保证线程安全
		s1.push(data);
	}
	
	public synchronized E pop() {
		if(!s2.isEmpty()) {
			return s2.pop();
		}else {
			s2.push(s1.pop());
			return s2.pop();
		}
	}
	
	public synchronized boolean isEmpty() {
		return s1.isEmpty() && s2.empty();
	}
	
}

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

队列的几种实现方式 的相关文章

  • 电路的频率响应

    文章目录 Frequency response Impedence Transfer function The Decibel scale First order circuits Series RL and RC circuits Ser
  • 3. C++ 数据类型

    目录 1 七种基本的 C 数据类型 2 C 中的变量定义 3 C 中的变量声明 4 C 变量作用域 局部变量 全局变量 1 七种基本的 C 数据类型 各种变量类型在内存中存储值时需要占用的内存 以及该类型的变量所能存储的最大值和最小值 注意

随机推荐

  • @ControllerAdvice 和 @ExceptionHandler注解处理全局异常

    ControllerAdvice 和 ExceptionHandler注解处理全局异常 处理全局统一异常 处理service层抛出异常的方法 异常体系 处理全局统一异常 在构建RestFul接口的今天 我们一般会限定好返回数据的格式 有利于
  • Nmap使用方法

    文章目录 1 Nmap简介 2 Nmap使用方法 3 扫描技术 4 端口指定和扫描顺序 5 举例 5 1 简单扫描 nmap ip 5 2 全面扫描 nmap A ip 5 3 探测指定端口的开放状态 5 4 探测N个最有可能开放的端口 5
  • 升级SQLite数据库

    一 步骤 1 在之前的基础上添加一张Category表 在onCreate 方法中执行建CREATE CATEGORY表语句 2 然后在onUpgrade 中执行两条drop语句 发现数据库表存在 就将已经存在的表格删除 再在onCreat
  • CISSP一次通过指南(文末附福利)

    2017年12月19日 在上海黄浦区汉口路亚洲大厦17层通过了CISSP认证考试 拖拉了一年 终于成绩还算令人满意 为攒人品将自己一年多的复习心得和大家分享 希望能够帮到需要考证的朋友 本文作者 i春秋签约作家 tinyfisher 欢迎与
  • 【JavaWeb】网络原理初识

    网络原理初识 计算机网络的历史 局域网和广域网 网络组件中的重要设备 网络通信基础 基本概念 协议分层 OSI七层模型 TCP IP五层 或四层 模型 封装和分用 发送方 接收方 三层转发和二层转发 计算机网络的历史 计算机最初是为了打仗而
  • python基础之数据类型知识(1)

    注释 注解 解释 说明文字而已 特征 注释只是用于说明的文字不会影响内容本身 作用 1 用于添加说明文字 方便阅读 2 用于调试程序 排查错误 分类 单行注释 多行注释 内容 或者 内容 代码 print hello world print
  • 利用JS实现简单的todoList(记事本)效果

    目录 1 实现效果展示 2 HTML代码 3 CSS代码 4 Javascript代码 该记事本程序利用HTML CSS JavaScript前端三大框架来实现 实现了记事本的添加 已完成和删除待办事项的基本功能 下面是程序实现的全部代码
  • 交通类SCI顶级期刊排名

    大多数期刊还是在IEEE http ieeexplore ieee org 或者ScienceDirect https www sciencedirect com 上面的 如果你是学生的话 可能从你们学校的图书馆可以进到这些网站去下载论文
  • Vue js引用警告 “export ‘default‘ (imported as ‘xxx‘) was not found

    问题原因 ES6 编译器识别问题 如果在public js这样写会有警告export default imported as xxx was not found export const myMixin 解决办法 修改组件中引用js的地方
  • Linux TCP链接查看和调整

    查看Linux的TCP连接数的方法如下 统计80端口连接数 netstat nat grep i 80 wc l 统计httpd协议连接数 ps ef grep httpd wc l 统计已连接上的 状态为 established 的TCP
  • Java终止线程的三种方式

    停止一个线程通常意味着在线程处理任务完成之前停掉正在做的操作 也就是放弃当前的操作 在 Java 中有以下 3 种方法可以终止正在运行的线程 使用退出标志 使线程正常退出 也就是当 run 方法完成后线程中止 使用 stop 方法强行终止线
  • R----dplyr包介绍学习

    dplyr包 plyr包的替代者 专门面对数据框 将ddplyr转变为更易用的接口 gt 来自dplyr包的管道函数 其作用是将前一步的结果直接传参给下一步的函数 从而省略了中间的赋值步骤 可以大量减少内存中的对象 节省内存 可惜的是应用范
  • 【理解springboot自动装配原理】

    理解springboot自动装配原理 最近读了小马哥 mercyblitz Springboot编程思想 核心篇 有了一些心得和感悟 分享给大家 1 官网介绍了激活自动装配的方法 文档提到激活自动化装配的注解 EnableAutoConfi
  • DAS、SAN、NAS存储连接方式详解

    1 直接访问存储DAS Direct Access Storage DAS将存储设备通过SCSI接口或光纤通道直接连接到一台计算机上 代表为磁盘阵列柜RAID 磁盘阵列柜是由多个硬盘按照不同的方式组合成一个大型的磁盘组 利用个别磁盘提供数据
  • Spring的xml文档配置

    1基于XML的注解配置
  • webpack 收集依赖、打包输出精简实现

    文章目录 安装babel插件 读取文件信息 获取当前js文件的依赖关系 广度遍历获取所有依赖图 生成浏览器可执行代码 安装babel插件 由于ES6转ES5中需要用到babel 所以要用到一下插件 npm install babel cor
  • MATLAB-DL6

    MATLAB DL6 步骤 交互式迁移貌似2020a才有 学会用analyze network 命令行式 迁移学习 冻结 freezeWeights createLgraphUsingConnections 数据增强 学习参数 函数大杂烩
  • SQL求解用户连续登录天数

    数据分析面试过程中 一般都逃不掉对SQL的考察 可能是笔试的形式 也可能是面试过程中面试官当场提问 当场在纸上写出 或者简单说一下逻辑 今天 就来分享一道面试中常常被问到的一类SQL问题 连续问题 无论是什么样的场景 只要是 连续 问题 那
  • TCP/IP协议之服务器端——华清远见

    咳咳咳 今天也是认真学习的一天 一 TCP IP协议是什么 TCP协议是一种以固连线为基础的协议 它提供两台计算机之间可靠的数据传送 TCP可以保证从一端数据传至连接的另一端时 数据能够确实送达 TCP协议适合可靠性比较高的场合 就像拨打电
  • 队列的几种实现方式

    队列简介 队列是一种特殊的线性表 特殊之处在于它只允许在表的前端 front 进行删除操作 而在表的后端 rear 进行插入操作 和栈一样 队列是一种操作受限制的线性表 进行插入操作的端称为队尾 进行删除操作的端称为队头 队列是一种最常用的