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

时光怂恿深爱的人放手 提交于 2019-12-06 01:57:50

For copying arrays with more than a handful of elements, use System.arraycopy(), since it is usually implemented as native code, e.g. Sun's VM uses hand-coded assembler.

front > rear

Since the data is contiguous, it can remain in the same place in the new array.

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

front <= rear

The data is non-contiguous, so copy both blocks to the start of the new array.

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

Thx a lot for your answers and different solutions! :)

Although using the System.arraycopy() method is the most easy and efficient solution, I had to avoid using it and implement a solution by myself.

So, if someone want to resize() a circular array in a queue implementation without System.arraycopy(), here is my final solution:

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;

}

As you can see, I took advantage of the "circular" thing and mapped the positions of the old array to the new array using the % operator.

The resultant array will have the double of capacity and all the elements (keeping the original order, obviously) at the beginning of the new array.

I've tested it and it worked properly. Lemme know if there is any inconvenience with that code.

Regards

Think of the blocks of array elements you want to move and where they should go in the new array. Then and use System.arraycopy to do it. You should call arraycopy once if front < rear and twice if rear < front.

If your array is full, you either have front == rear - 1, or rear == 0 and front == length -1 (or the other way around, I don't know your nomenclature). In the second case you can copy your whole array in one step, in the (more general) first case you have two blocks (0 .. front and rear .. length-1) which are to copy.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!