队列数据结构 – 定义和 Java 示例代码

在本文中,我们将讨论队列数据结构,其操作以及如何在Java中使用数组实现这些操作。

什么是队列?

队列是线性数据结构,它由遵循先进先出序列的项组成的集合组成。这意味着要插入的第一个项目将是要删除的第一个项目。您也可以说项目按照插入的顺序被删除。

使用一个真实的例子,我们可以将队列数据结构与排队等待服务的人员队列进行比较。一旦一个人被照顾,他们就会离开队列,等待下一个人照顾。他们按照他们来的顺序得到帮助。

队列的结构

队列主要由两部分组成:前/头和后/尾/后。为了清晰和一致,我们将坚持使用正面和背面。

背面是插入项目的位置,前端是队列中移除/删除项目的部分。

下图可帮助您更好地理解:

该图显示了一个包含各种单元格的数组。物品从背面插入,然后通过正面取下。有一些术语用于插入和删除队列中的项目,我们将在下一节中介绍这些术语。

请注意,您可以反转队列的结构 - 您可以将前面放在右侧,将背面放在左侧。无论您采用哪种结构,请始终记住,项目的插入通过背面进行,删除通过正面进行。

队列的常见操作

队列中通常使用以下操作:

  • 排队:从队列后面添加项目。

  • 取消排队:从队列前面删除项目。

  • Front/Peek:返回队列前面的项的值,而不对该项进行取消排队(删除)。

  • 是空:检查队列是否为空。

  • 已满:检查队列是否已满。

  • 显示:打印队列中的所有项目。

在了解如何使用代码实现此操作之前,您需要了解排队取消排队操作的工作原理以及它们如何影响前后位置。

大多数编程语言中的数组索引从 0 开始。在实现代码时,我们将数组的前后值的索引设置为 -1。这将使我们能够在添加值时正确移动前后位置。

考虑下图:

箭头显示了数组的正面和背面的位置。当两个位置都位于 -1 时,表示数组为空。

让我们将一些项添加到数组中,看看会发生什么。

我们已经插入(排队)了我们的第一个项目 - 5。前后的位置也发生了变化。接下来,我们将看到在排队更多项目时会发生什么

添加了第二个项目,但仅移动了后部。随着我们排入更多项目的排队,这种情况将继续下去。在最后一个示例中,前面和后面一起移动,以便前面可以假定第一个项目的位置。

由于这是当时的第一个也是唯一一个项目,因此前后都坐在那个位置。但是现在我们已经排入了更多项目,背面将继续跟随最后一个项目。

我们将继续填充数组,以便我们可以看到取消排队时会发生什么。

因此,后退箭头按照项目添加的顺序一直跟随到最后一个。现在,让我们删除(取消排队)一些项目。

还记得先到先出的顺序吗?当我们执行取消排队操作时,它将首先从队列中删除 5。如果我们再次执行它,那么它将移动到下一个数字10,并按照该顺序继续,只要我们调用它。

这里,第一个取消排队操作:

现在,前面的箭头已移至索引 1。这意味着索引 0 处的项目已被删除。通过删除,我们不是指从数组中,而是从队列中移除 - 只有从前部位置到后部位置的项目才是队列的一部分。

按照相同的顺序,如果我们继续删除项目,它将到达前箭头与队列末尾的后箭头相遇的点。如果我们在该点再次取消排队,则前箭头将移过后退箭头,然后队列将被视为空,因为那里没有要删除的内容。发生这种情况时,我们会将其索引重置为 -1(其初始起点)。

是时候编写一些代码了!

Java 中的队列实现

我们将通过创建每个操作,然后将所有内容放在最后来分解此部分。

int queueLength = 3;
int items[] = new int[queueLength];
int front = -1; 
int back = -1;

我们已经创建了变量及其参数。我们使用 3 作为数组中可以排队的最大项目数。就像我们在上一节中的图像中看到的那样,我们将前后方的初始索引设置为-1。

接下来,我们将定义 isEmpty 和 isFull 功能。

对于是空:

boolean isEmpty(){
      if(front == -1 && back == -1){
          return true;
      } else {
          return false;
      }
  }

如果你在最后一节中跟随,很容易掌握。仅当前后索引为 -1 时,数组才为空。

对于 isFull

boolean isFull(){
      if(back == queueLength - 1){
          return true;
      } else {
          return false;
      }
  }

这个可能看起来有点棘手,但这是逻辑:数组中允许的最大项目数是3,但数组中的三个项目不是用索引3表示的,而是用2表示的,因为第一个索引是0。因此,最大长度减去1会给我们索引2,这是数组中的第三个单元格。

当所有单元格都已排队并附加到第三个单元格的值时,数组已满。

对于 enQueue

void enQueue(int itemValue) {
      if(isFull()){
          System.out.println("Queue is full");
      } else if(front == -1 && back == -1){
          front = back = 0;
          items[back] = itemValue;
      } else{
          back++;
          items[back] = itemValue;
      }
  }

如果数组已满,则我们收到一条消息,指出它已满。如果前后为 -1,则将该项目分配给索引为 0 的第一个单元格 , 否则,将插入该值并递增后退位置。

对于取消排队

void deQueue(){
      if(isEmpty()){
          System.out.println("Queue is empty. Nothing to dequeue");
      } else if (front == back){
          front = back = -1;
      } else {
          front++;
      }
  }

在这里,如果数组为空,我们会得到相应的消息。如果正面与背面相遇,我们会将其索引重置为-1,就像我们在上一节中的图像中看到的那样。如果最后两个条件不适用,则前面递增。

对于显示

void display(){
      int i;

      if(isEmpty()){
          System.out.println("Queue is empty");
      } else {
          for(i = front; i <= back; i++){
              System.out.println(items[i]);
          }
      }
  }

在这里,如果数组不为空,我们循环并打印所有项目。

最后,对于窥视

void peak(){
      System.out.println("Front value is: " + items[front]);
  }

这只会打印前面项的值。

这些都是我们队列的所有操作。以下是下面一个整体:

// Queue implementation in Java

public class Queue {

  int queueLength = 3;
  int items[] = new int[queueLength];
  int front = -1; 
  int back = -1;

  boolean isFull(){
      if(back == queueLength - 1){
          return true;
      } else {
          return false;
      }
  }

  boolean isEmpty(){
      if(front == -1 &amp;&amp; back == -1){
          return true;
      } else {
          return false;
      }
  }

  void enQueue(int itemValue) {
      if(isFull()){
          System.out.println("Queue is full");
      } else if(front == -1 &amp;&amp; back == -1){
          front = back = 0;
          items[back] = itemValue;
      } else{
          back++;
          items[back] = itemValue;
      }
  }

  void deQueue(){
      if(isEmpty()){
          System.out.println("Queue is empty. Nothing to dequeue");
      } else if (front == back){
          front = back = -1;
      } else {
          front++;
      }
  }

  void display(){
      int i;

      if(isEmpty()){
          System.out.println("Queue is empty");
      } else {
          for(i = front; i <= back; i++){
              System.out.println(items[i]);
          }
      }
  }

  void peak(){
      System.out.println("Front value is: " + items[front]);
  }

}

现在让我们执行这些操作:

 public static void main(String[] args) {
    Queue myQueue = new Queue();

    myQueue.enQueue(3);
    myQueue.enQueue(2);
    myQueue.enQueue(1);

    myQueue.display();

    myQueue.peak();

  }

enQueue(3) 将 3 插入到我们的队列中,类似于接下来的两行代码。

display() 打印出数组中的项。

peak() 打印前面项的值。

我们没有执行,因此您可以继续自己尝试 - 显示您的数组并在取消排队后看一眼,看看会发生什么。有多种方法可以修改代码,所以玩得开心! deQueue

结论

在本文中,我们定义了一个队列及其结构。我们继续看到一些使用图像的示例,以显示队列的前后位置在项目排队和取消排队时的反应。

最后,我们看到了如何在Java中使用数组实现队列数据结构。

感谢您的阅读和快乐的编码!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

库特社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值