繁体   English   中英

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

[英]Queue implementation with circular arrays: Which is the best way to resize a circular array?

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

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

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

  1. 前面<=后面
  2. 后<前

将旧数组的元素复制到新的较大数组中的最佳方法是什么?

我认为它使用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并调整大小

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

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

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

前>后

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

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

前面<=后面

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

// 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;

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

虽然使用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知道该代码是否有任何不便之处。

问候

想想要移动的数组元素块以及它们应该在新数组中的位置。 然后使用System.arraycopy来完成它。 如果前<后部,则应调用一次arraycopy;如果前部<前部,则应调用两次。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM