[英]Queue implementation with circular arrays: Which is the best way to resize a circular array?
我正在使用循環數組實現一個隊列 ,我有點陷入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
並調整大小
我不確定用於做這件事的數量,我擔心我會失去價值觀。
有人能告訴我是否有更好的方法嗎?
要復制具有多個元素的數組,請使用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 == 0
和front == length -1
(或者相反,我不知道你的命名法)。 在第二種情況下,您可以一步復制整個數組,在(更一般)第一種情況下,您有兩個要復制的塊(0 ..前后..長度-1)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.