我正在使用循环数组实现队列,而且我有点陷入resize()
方法实现(当数组已满时)。
在enqueue()
方法中,我检查数组的大小是否等于它的长度,如果它已满,则检查它。现在,我没有抛出异常,而是试图调整数组的大小。
问题是,我有两个案例要考虑
将旧数组的元素复制到新的更大的的最佳方法是什么?
我认为它使用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
并调整大小
我不确定用于做这件事的数量,我担心我会失去价值。
有人能告诉我是否有更好的方法吗?
答案 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 == 0
和front == length -1
(或者相反,我不知道你的命名法)。在第二种情况下,您可以在一个步骤中复制整个数组,在(更一般)第一种情况下,您有两个块(0 ..前后..长度为1)要复制。