使用循环数组实现队列:哪种方法可以调整圆形数组的大小?

时间:2011-04-17 17:17:12

标签: java arrays resize queue circular-buffer

我正在使用循环数组实现队列,而且我有点陷入resize()方法实现(当数组已满时)。

enqueue()方法中,我检查数组的大小是否等于它的长度,如果它已满,则检查它。现在,我没有抛出异常,而是试图调整数组的大小。

问题是,我有两个案例要考虑

  1. front< = rear
  2. 后<前
  3. 将旧数组的元素复制到新的更大的的最佳方法是什么?

    我认为它使用for循环,如:

    newArray = new Array[oldArray.length*2];
    
    if (front <= rear) {
        for (int i = front; i < rear; i++) {
            newArray[i] = oldArray[i];
        } 
    } else {
        for (int i = front; i < newArray.length; i++) {
            newArray[i] = oldArray[i];
        }
    
        for (int j = rear; j < front; j++) {
            // i'm using the variable i, the order is maintained
            newArray[i] = oldArray[j];
            i++;
        }
    }
    

    然后oldArray = newArray,返回newArray并调整大小

    我不确定用于做这件事的数量,我担心我会失去价值。

    有人能告诉我是否有更好的方法吗?

4 个答案:

答案 0 :(得分:5)

要复制包含多个元素的数组,请使用System.arraycopy(),因为它通常是作为本机代码实现的,例如Sun的VM使用手动编码的汇编程序。

正面&gt;后

由于数据是连续的,因此它可以保留在新数组中的相同位置。

System.arraycopy(oldArray, front, newArray, front, front-rear);

前面&lt; =后面

数据是非连续的,因此将两个块复制到新数组的开头。

// copy [rear to end]
System.arraycopy(oldArray, rear, newArray, 0, oldArray.length-rear);
// copy [0 to front]
System.arraycopy(oldArray, 0, newArray, oldArray.length-rear, front);
front = oldArray.length-(rear-front);
rear = 0;

答案 1 :(得分:2)

很多答案和不同的解决方案! :)

尽管使用System.arraycopy()方法是最简单有效的解决方案,但我必须避免使用它并自行实现解决方案。

所以,如果有人想要在没有System.arraycopy()的队列实现中调整圆形数组的大小(),这是我的最终解决方案:

private void resize() {

    E[] aux = (E[]) new Object[Q.length * 2]; // new array

    int i = 0; // use this to control new array positions
    int j = f; // use this to control old array positions

    boolean rearReached = false;

    while (!rearReached) {

        rearReached = j % Q.length == r; // is true if we've reached the rear

        aux[i] = Q[j % Q.length];

        i++;
        j++;

    }

    f = 0;
    r = Q.length - 1;
    Q = aux;

}

正如你所看到的,我利用了“循环”的东西,并使用%运算符将旧数组的位置映射到新数组。

结果数组将具有容量的两倍和所有元素(显然保持原始顺序)在新数组的开头。

我已经测试过了,它运行正常。 Lemme知道该代码是否有任何不便。

此致

答案 2 :(得分:0)

考虑要移动的数组元素块以及它们应该在新数组中的位置。然后使用System.arraycopy来完成它。如果前面的话,你应该调用一次arraycopy。后部和后部两次&lt;前面。

答案 3 :(得分:0)

如果你的阵列已满,你要么front == rear - 1,要么rear == 0front == length -1(或者相反,我不知道你的命名法)。在第二种情况下,您可以在一个步骤中复制整个数组,在(更一般)第一种情况下,您有两个块(0 ..前后..长度为1)要复制。