当前位置: 首页 > 知识库问答 >
问题:

为什么基于数组的队列不能正常工作?

朱皓
2023-03-14

我已经为基于数组的队列编写了一个代码。它的行为非常奇怪,就像我使用for循环将0,1,2,3,4排队一样,但是插入队列的是0,0,1,2,3。

另外,出列时会抛出ArrayOutOfBoundsException,我不知道为什么。

我使用的排队逻辑是,我把元素放在一个简单的数组中。额外的一点是,如果大小接近容量的一半,我会增加数组的容量。

对于出列,如果大小小于容量的三分之一,我将减小容量。我还为popped保留了一个计数器,它从数组的开头弹出元素。

以下是我使用过的代码:

class ArrayQueue {

      private int[] arr;
      private int size;
      private int capacity;
      private int popped = 0;

      public ArrayQueue(int capacity) {

        this.capacity = capacity;
        size = 0;
        arr = new int[capacity];
      }

      public int size() {
        return size;
      }

      public int capacity() {
        return capacity;
      }

      public void enqueue(int ele) {

        size++;

        if(size >= capacity/2) {

            capacity = capacity*2;

            int[] nArr = new int[capacity];

            for(int i=0;i<size;i++)
                nArr[i] = arr[i];

            arr = nArr;

        }

        arr[size] = ele;

      }

      public void dequeue() {

        size--;

        System.out.println(arr[popped]+" removed");

        if(size <= capacity/3) {

            capacity = capacity/2;

            int[] nArr = new int[capacity];

            for(int i=0;i<size;i++)
                nArr[i] = arr[i];

            arr = nArr;

        }

        int[] nArr = new int[capacity];

        for(int i=0;i<popped;i++)
            nArr[i] = arr[i];

        for(int i=popped+1;i<size;i++)
            nArr[i-1] = arr[i];

        arr = nArr;

        popped++;

    }

    public boolean isEmpty() {
        return (size == 0);
    }

    public void showQueue() {

        for(int i=0;i<size;i++)
            System.out.println("| "+arr[i]+" |");

    }
    }



    public static void main(String[] args) {

        ArrayQueue a = new ArrayQueue(10);

        System.out.println("Starting size "+a.size());

        for(int i=0;i<5;i++) {

            a.enqueue(i);
            System.out.println("Current size is "+a.size());
            System.out.println("Current capacity is "+a.capacity());

        }

        System.out.println();

        a.showQueue();

        System.out.println();

        a.dequeue();

        System.out.println("Size: "+a.size());
        System.out.println("Current capacity is "+a.capacity());

        a.dequeue();

        System.out.println("Size: "+a.size());
        System.out.println("Current capacity is "+a.capacity());

        a.dequeue();

        System.out.println("Size: "+a.size());
        System.out.println("Current capacity is "+a.capacity());

        a.dequeue();

        System.out.println("Size: "+a.size());
        System.out.println("Current capacity is "+a.capacity());


    }

我得到的结果是:

Starting size 0
Current size is 1
Current capacity is 10
Current size is 2
Current capacity is 10
Current size is 3
Current capacity is 10
Current size is 4
Current capacity is 10
Current size is 5
Current capacity is 20

| 0 |
| 0 |
| 1 |
| 2 |
| 3 |

0 removed
Size: 4
Current capacity is 10
1 removed
Size: 3
Current capacity is 5
0 removed
Size: 2
Current capacity is 5
0 removed
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
    at ArrayQueue.dequeue(Code.java:228)
    at Code.main(Code.java:76)

共有2个答案

晋骏喆
2023-03-14

对于enqueue,您的代码应该如下所示。在您的代码中,当您之前增加大小时,它会出现问题。

public void enqueue(int ele) {



      if(size >= capacity/2) {

          capacity = capacity*2;

          int[] nArr = new int[capacity];

          for(int i=0;i<size;i++)
              nArr[i] = arr[i];

          arr = nArr;

      }

      arr[size] = ele;
      size++;

    }

对于出列,您不应该在每次需要删除0索引时基于Popped执行操作。

    public void dequeue() {

    System.out.println(arr[0] + " removed");
    if (size <= capacity / 3) {
        capacity = capacity / 2;
        int[] nArr = new int[capacity];
        for (int i = 0; i < size; i++)
            nArr[i] = arr[i];
        arr = nArr;
    }

    int[] nArr = new int[capacity];

    for (int i = 1; i < size; i++) // every time we need to pop first index
        nArr[i - 1] = arr[i];

    arr = nArr;

    popped++;
    size--;

}
叶琦
2023-03-14

执行deQueue()操作时,应始终删除索引0处的元素。所以你不需要增量弹出。它应该总是0(索引0)

    public void dequeue() {

        size--;

        System.out.println(arr[popped] + " removed");

        if (size <= capacity / 3) {

            capacity = capacity / 2;

            int[] nArr = new int[capacity];

            for (int i = 0; i < size; i++)
                nArr[i] = arr[i];

            arr = nArr;

        }

        int[] nArr = new int[capacity];

/*      for (int i = 0; i < popped; i++)
            nArr[i] = arr[i]; //Not required as popped is always 0
*/
        for (int i = popped + 1; i < size; i++)
            nArr[i - 1] = arr[i];

        arr = nArr;

        //popped++; // not required as we remove first element

    } 
 类似资料:
  • 我正在使用Java NIO,由于某种原因,我无法获得files.isHidden()来返回正确的布尔值。程序只是检查目录是否隐藏,如果隐藏,则使其可见,如果不隐藏,则使其隐藏。这就是我所拥有的: 它继续返回false并隐藏目录,尽管目录被隐藏。下面的代码使用旧的File类和Path类可以很好地工作。

  • 我一直在用SceneBuilder 9.0.1在IntelliJ上做一个项目。昨天,在NetBeans 8上做了一个小型项目,12之后由于某种原因没有启动新项目。一旦关闭所有内容并打开IntelliJ项目,fxml文档就无法使用SceneBuilder打开。对于这个问题,需要注意以下几点: 我使用的是9.0.1版,尽管v15也有同样的问题, 其中一个fxml文件的示例如下: 请帮助。

  • 我正在尝试制作一个简单的Pygame应用程序,其中一些颜色与它们下面的颜色混合。以下是我的代码: 代码列表1: 代码应该使黄色矩形与橙色矩形混合,蓝色矩形与绿色矩形混合。相反,我从中得到了一些东西: 对此: 正如你所看到的,黄色和蓝色矩形不仅与红色矩形(屏幕表面)相融合,而且还为橙色和绿色矩形开了一个洞,这样我们就可以通过它们看到红色矩形。

  • 问题内容: 作为回答另一个问题的一部分,我编写了以下代码,乍看之下其行为似乎很奇怪: 谁能解释这个奇怪的行为?我认为这与Python的对象模型有关,但我不确定。 Cygwin下的版本2.5.2。 问题答案: Python具有这两个(以及其他)内置对象。它们只是对象。刚开始时,它们还没有任何名称,但是要知道我们指的是什么,我们将它们称为和。 在开始执行Python(2.x)脚本之前,该名称已绑定到该

  • 我试图在一个变量中保存得分为80分或80分以上的学生的姓名,但我无法使用filter进行保存,它返回整个对象,尽管我指定只打印这些对象的键值,即这些学生的姓名。 我的代码: 我怎样才能得到得分在80分以上的学生的名字?

  • 我使用react和laravel开发了一个应用程序来显示酒店列表。当用户点击一个单一的酒店,我希望该酒店的细节显示在一种类型的‘单一’视图。然而,尽管在主列表视图中,我使用正确的路由模式链接到单个页面,并且我在路由器中定义了该模式,但当我单击该链接时,我会被带到一个“404 not found”页面。 编辑文章的编辑链接也是如此。 任何关于如何解决这个问题的想法都将非常感谢! 谢谢, 罗伯特·杨