Очереди в Java. Что не так с моей реализацией и какую из них я могу использовать?

Я пытаюсь выполнить поиск в ширину, чтобы решить головоломку со сдвигом квадратов (та, где вы перемещаете квадраты в пустое пространство, пока она не будет решена). Мой алгоритм поиска в ширину использует очередь. К сожалению, кажется, что это работает только для случаев UP и DOWN, а не для случаев LEFT или RIGHT:

                if (up)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x - 1][y];
                current[x - 1][y] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

            if (down)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x + 1][y];
                current[x + 1][y] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

            if (left)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x][y - 1];
                current[x][y - 1] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

            if (right)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x][y + 1];
                current[x][y + 1] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

Думаю проблема с моей очередью, реализация которой ниже. Что-то не так с моей очередью или это другая проблема? Есть ли в Java API класс очереди, который я мог бы использовать?

public class ArrayQueue {
State[] items;
int maxSize;
int front;
int rear;
int numItems;

public ArrayQueue(int max)
{
    items = new State[max];
    maxSize = max;
    front = 0;
    rear = -1;
    numItems = 0;
}

public boolean insert(State item)
{
    if (isFull()) return false;
    rear = (rear + 1) % items.length;
    items[rear] = item;
    return true;
}

public State remove()
{
    if (isEmpty()) return null;
    State removed = items[front];
    front = (front + 1) % items.length;
    return removed;
}

public boolean isFull()
{
    if ((front + 1) % maxSize == rear)
        return true;
    else
        return false;
}

public boolean isEmpty()
{
    if ((rear + 1) % maxSize == front)
            return true;
    else
        return false;
}
}

Вот метод копирования:

public static int[][] copy(int[][] input)       //This method is necessary because we are trying to clone a multi-dimensional array.
{                                               //Just using clone() will copy the outer arrays but they will be arrays of references to the original inner arrays.
int[][] output = new int[input.length][];
for (int i = 0; i < input.length; i++)
    output[i] = input[i].clone();
return output;
}

person Andrew Latham    schedule 29.11.2011    source источник
comment
Как насчет Queue?   -  person Oliver Charlesworth    schedule 29.11.2011
comment
Есть ли в Java API класс очереди, который я мог бы использовать? Вы его искали? документация по API находится в сети, и вы должны иметь их в закладках.   -  person Hot Licks    schedule 29.11.2011
comment
И почему вы подозреваете свою очередь, если она работает вверх/вниз, но не влево/вправо?   -  person Hot Licks    schedule 29.11.2011
comment
Для меня наиболее заметное различие между вашими случаями вверх/вниз и левыми/правыми случаями заключается в том, что первые перемещают квадрат из одного int[] в другой, а вторые перемещают квадрат внутри одного и того же int[]. Это заставляет меня задаться вопросом, может ли проблема быть на самом деле в вашем методе copy; если он делает только одну глубокую копию, вы увидите различное поведение между этими двумя случаями.   -  person ruakh    schedule 29.11.2011
comment
@HotLicks Не нужно быть таким насмешливым. Когда я ищу в Google, все, что я вижу, это интерфейс, и когда я все равно пытаюсь использовать его, просто на случай, если там может быть класс Queue, я получаю сообщение об ошибке Невозможно создать экземпляр типа Queue‹State›.   -  person Andrew Latham    schedule 29.11.2011
comment
@ruakh Я не вижу проблемы в методе копирования, но я отредактировал вопрос, добавив код в конце.   -  person Andrew Latham    schedule 29.11.2011
comment
@AndrewLatham: согласен, твой copy выглядит нормально. Плевать на эту мысль. :-)   -  person ruakh    schedule 29.11.2011


Ответы (2)


JDK предоставляет интерфейс Queue и ряд реализаций, которые можно найти в разделе «Все известные классы реализации» в Queue документация.

Для ваших целей LinkedList, вероятно, следует достаточно хорошо.

person Mansoor Siddiqui    schedule 29.11.2011
comment
Queue‹State› q = new LinkedList‹State›(); это то, что я использовал. Спасибо! - person Andrew Latham; 29.11.2011

Я думаю, что проблема в «передних» и «задних». Они должны указывать на одну и ту же позицию 0 в начале, поэтому, когда они равны, очередь пуста. «Задняя» будет указывать на позицию для записи (запись, а затем сдвиг вперед), а «передняя» — на позицию для чтения (чтение, а затем сдвиг). «Задний», кажется, движется быстрее, пока очередь заполняется. Когда он дойдет до конца, он вернется к нищенству. Таким образом, вам нужно будет выполнить (сзади + 1)% max == спереди, чтобы проверить, можете ли вы безопасно вставить новый элемент.

Кроме того, рассмотрите возможность использования некоторых стандартных реализаций, как предложил г-н Сиддики.

person sviklim    schedule 29.11.2011