Java实现基本数据结构(三)——队列

本文介绍了队列数据结构的基本概念和应用,重点讲述了在Java中使用线性存储(数组)实现队列的过程,包括设计队列功能、实现Queue接口、数组实现的一般队列及其时间复杂度分析。还详细讲解了如何优化数组队列,引入循环队列的概念,以及循环队列的实现和时间复杂度分析。
摘要由CSDN通过智能技术生成

前言

  阅读本文前,最好先学习顺序表和栈的基本操作和实现原理,也就是弄清楚数组和栈的原理,点击Java实现基本数据结构(一)——数组Java实现基本数据结构(二)——栈。先学习前置内容,学习效果更好哦!


队列简介

  在数据结构中,队列和栈(Java实现基本数据结构(二)——栈)类似,也是一种线性表的结构。不同的地方在于栈只允许数据从一端进行插入和删除,而队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。根据这一种操作限制,我们将队列入队(插入操作)的一端称为队尾,出队(删除操作)的一端称为队首。所以队列也被称作为先进先出表(FIFO:First In First Out)。如下面图片所示,展示了一个队列的结构示意,入队和出队的操作示意:
队列示意
            图1 队列结构示意
在这里插入图片描述
            图2 出队操作示意
在这里插入图片描述
            图3 入队操作示意图


初识队列的应用

  队列在计算机系统中也是一个应用非常广泛的数据结构。队列在设计程序中用的非常频繁,比如用用户用键盘输入内容后在显示器上显示出来这一过程,其实就是对列的典型应用,比如你输入了一个英文单词god,应用队列可以让显示和你的输入顺序一致,先输入的先输出,否则显示出dog可就真让人恼火了。
  还有,我们会在用电脑时,偶尔会出现电脑处于疑似死机的状态,鼠标点什么似乎都没用,双击任何快捷方式都不动弹。就当你失去耐心,打算重启时。突然他像酒醒了一样,把你刚才点击的所有操作全部按顺序执行一遍。这其实是因为操作系统中的多个程序因需要通过一个通道输出,而按先后次序排队等待造成的。


  在队列这种数据结构的具体实现上,一般也有两种实现方式:线性存储和链接存储(链表)。也就是使用数组和链表这两种数据结构都可以实现队列。
  下面我们分别对这两种方法进行实现。


在Java中使用线性存储实现队列结构

  在Java语言中,使用线性存储实现队列,和栈的实现思路一样,实际上就是使用数组这样一种结构,并对其操作进行限制来实现队列。也就是说实际上,对比数组,线性存储队列对应的操作就是数组的子集。
  也就是说,我们实际上可以把队列这种结构看成一个特殊的数组,这个数组只能从一端添加元素,这一端称之为队尾(rear);却只能从另外一端取出元素,这一端称之为队首(front)。
  和数组一样,线性存储的队列在使用时是静态分配的,就是使用的时候,内存已经以数组的形式开辟了一段空间,所以在初始化的时候,我们需要给定一个长度。

设计队列的功能

  根据队列这种数据结构的特点,在队列的实现上,我们只需要设计以下几个功能即可:
  (1)入队(enqueue)操作:将一个元素插入队列中,实际上就是插入数组的尾部。
  (2)出队(dequeue)操作:将队首元素出队,实际上就是将数组头部的元素删除,并返回这个元素。
  (3)查看队首元素(getFront)操作:将队首的元素返回给用户,实际上就是返回数组头部元素。
  (4)返回栈的元素个数。
  (5)判断栈是否为空。
  因为我们前面说过,队列这种数据结构可以有两种实现方式,一种是线性存储,即通过数组实现;一种是链接存储,即通过链表实现。为了方便后续的实现,我们首先定义一个Queue接口,后面分别用数组和链表来实现这个接口即可。

实现Queue接口

  按照上一小节的设计,我们直接在接口中约定这些功能即可。


public interface Queue<E> {
   
	
	int getSize();
	boolean isEmpty();
	void enqueue(E e);
	E dequeue();
	E getFront();
	
}

通过数组实现Queue接口

  为了更好的让本系列文章之间更好的串联知识点,本节实现的线性存储队列,将不使用JDK提供的ArrayList,使用Java实现基本数据结构(一)——数组中已经实现好的ArrayList类作为队列的存储结构。实际上,使用JDK提供的ArrayList类实现队列的方法是一样的,大家可以自行练习。
  由于队列的功能比较简单,而且和栈的操作类似,这里直接对队列进行代码实现,相关细节在注释中体现。


public class ArrayQueue<E> implements Queue<E> {
     // 泛型
	
	// 定义一个数组用来存储队列中的元素
	private ArrayList<E> array;

	// 无参构造,直接使用ArrayList类中定义的无参默认值
	public ArrayQueue() {
   
		array = new ArrayList<E>();
	}

	// 有参构造,指定初始队列容量
	public ArrayQueue(int capacity) {
   
		array = new ArrayList<E>(capacity);
	}
	
	// 返回栈的元素个数,其实就是返回array的元素个数,调用array中的getSize()方法即可
	@Override
	public int getSize() {
   
		return array.getSize();
	}

	// 返回栈的总体容量大小,同上,就是返回array的容量空间
	public int getCapacity() {
   
		return array.getCapacity();
	}
	
	// 返回栈是否为空,其实就是返回array是否为空,调用array中的isEmpty()方法即可
	@Override
	public boolean isEmpty() {
   
		return array.isEmpty(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值