Как заполнить массив узловых элементов из двоичного дерева поиска, в порядке возрастания?

голоса
0

В школьном задании я должен завершить метод, который должен возвращать массив узловых элементов в порядке ascendig. Узлы собраны в бинарном дереве поиска, поэтому сортировать их правильно, я получил совет, чтобы создать рекурсивный метод, чтобы сделать работу.

Проблема заключается в том, что это даже не дают все элементы в коллекции в соответствии с выходным тест (java.lang.AssertionError:. ToArray () не возвращает все элементы в коллекции)

Я не мог придумать какой-либо другим способом, чтобы иметь дело с массивом, и я не совсем уверен, если рекурсия даже работает. Буду признателен за любую оказанную помощь. Ниже мой код:

public class BinarySearchTree<E extends Comparable<E>> implements
    IfiCollection<E> {

    Node root;
    Node current;
    int size = 0;
    int i = 0;

    public class Node {
    E obj;
    Node left, right;

    public Node(E e) {
        obj = e;
    }

    } // END class Node

    [...]

    public E[] toArray(E[] a) {

    Node n = root;

    a = sort(n, a);
    return a;

    }

    public E[] sort(Node n, E[] a) { //, int idx, E[] a) {

    if (n.left != null) {
        current = n.left;
        sort(current, a);
    }


    a[i] = current.obj;
    i++;

    if (n.right != null) {
        current = n.right;
        sort(current, a);
        }

    return a;

    } // END public Node sort

    [...]

} // END class BinarySearchTree

Результат теста:

java.lang.AssertionError: ToArray () не возвращает все элементы в коллекции .: TestPerson ( Bender) СотрагеТо (TestPerson ( Фрай)) == 0 ожидалось:. правда, но была ложь в inf1010.assignment .IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:74) в inf1010.assignment.IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:83) в inf1010.assignment.IfiCollectionTest.assertCompareToEqualsNoOrder (IfiCollectionTest.java:100) в inf1010.assignment.IfiCollectionTest.toArray ( IfiCollectionTest.java:202)

protected void assertCompareToEquals(TestPerson actual,
        TestPerson expected, String msg) {
            assertTrue(actual.compareTo(expected) == 0, String.format( // l:74
            %s: %s.compareTo(%s) == 0, msg, actual, expected));
}

    [...]

protected void assertCompareToEquals(TestPerson[] actual,
        TestPerson[] expected, String msg) {
    for (int i = 0; i < actual.length; i++) {
        TestPerson a = actual[i];
        TestPerson e = expected[i];
        assertCompareToEquals(a, e, msg); // l:83
    }
}

    [...]

protected void assertCompareToEqualsNoOrder(TestPerson[] actual,
        TestPerson[] expected, String msg) {
    assertEquals(actual.length, expected.length, msg);

    TestPerson[] actualElements = new TestPerson[actual.length];
    System.arraycopy(actual, 0, actualElements, 0, actual.length);

    TestPerson[] expectedElements = new TestPerson[expected.length];
    System.arraycopy(expected, 0, expectedElements, 0, expected.length);

    Arrays.sort(expectedElements);
    Arrays.sort(actualElements);

    assertCompareToEquals(actualElements, expectedElements, msg); // l:100
}

    [...]

@Test(dependsOnGroups = { collection-core },
    description=Tests if method toArray yields all the elements inserted in the collection in sorted order with smallest item first.)
public void toArray() {
    TestPerson[] actualElements = c.toArray(new TestPerson[c.size()]);

    for (int i = 0; i < actualElements.length; i++) {
        assertNotNull(actualElements[i],
                toArray() - array element at index  + i +  is null);
    }

    TestPerson[] expectedElements = allElementsAsArray();
    assertCompareToEqualsNoOrder(actualElements, expectedElements, // l:202
            toArray() does not return all the elements in the collection.);

    Arrays.sort(expectedElements);
    assertCompareToEquals(actualElements, expectedElements,
            toArray() does not return the elements in sorted order with 
                    + the smallest elements first.);


    TestPerson[] inArr = new TestPerson[NAMES.length + 1];
    inArr[NAMES.length] = new TestPerson(TEMP);
    actualElements = c.toArray(inArr);
    assertNull(actualElements[NAMES.length],
            The the element in the array immediately following the 
            + end of the list is not set to null);
}

Я не знаю, должен ли я опубликовать больше тестовый код, это довольно обширное, и это может быть слишком много для одного поста?

Задан 18/03/2011 в 13:02
источник пользователем
На других языках...                            


4 ответов

голоса
0

Я думаю , где вы запутались в том , что если вы проверить, как бинарное дерево поиска работы, является то , что она всегда сортируется. Вы начинаете в корневой узел, а затем вставить новый узел, он вставляет его в соответствующее положение (т.е. влево или вправо) , в зависимости от значений. Таким образом , вы не должны называть своего рода , чтобы начать с. Поэтому я хотел бы начать там, и читать на бинарных деревьев поиска. Например википедии есть приличная статья.

Обновление: Игнорировать мой комментарий вы не должны делать что либо. Предположим, вы вставки 8, 3, 7, 9, 12, 2, 10, 1 в дерево, в указанном порядке. Он должен закончить тем, что, как это:

      8
     / \
    3   9
   / \   \
  2   7   12
 /       /
1       10

Если вы посмотрите на него, что значит получить их в порядке, начните с корнем, а затем, если он имеет узел слева получил слева, если нет, то вернуть себе, и идти направо, если это имеет значение. Повторяя эту процедуру для каждого узла вы сталкиваетесь.

Ответил 18/03/2011 в 13:30
источник пользователем

голоса
1

Я вижу, у вас есть код

if (n.left != null) {
        current = n.left;
        sort(current, a);
  }

но я не могу найти в какой момент вы установите тока назад на текущем узле, так что, когда вы делаете

a[i] = current.obj;

вы получите правильный результат. Это, вероятно, почему вы не получаете все результаты. В любом случае, я не вижу (по крайней мере из фрагментов коды вы выложили) почему ток должна быть переменным класс, а не только объявлено в методе сортировки. В общем, вы не должны использовать переменный класс, если вы на самом деле не нужны.

Edit: Вы можете установить ток обратно к узлу вы обрабатываете после вызова вида слева ребенка , как это

current = n;
a[i] = current.obj;
i++;

Или не использовать ток вообще в этом случае вы бы что-то вроде

if (n.left != null)
    sort(n.left, a);
a[i] = n.obj;
i++;
if (n.right != null)
    sort(n.right, a);
Ответил 18/03/2011 в 13:57
источник пользователем

голоса
0

http://cs.armstrong.edu/liang/intro8e/html/BinaryTree.html

Самый простой способ сделать то, что вы ищете, чтобы перемещаться по дереву заказовМои и добавить к ArrayList. Чтобы получить массив, который вы можете вызвать метод .toArray () в ArrayList.

Если вы не можете использовать ArrayList, объявить индекс и массив вне inordertraversal и приращения, вы должны будете знать, сколько элементов в дереве, чтобы объявить массив.

псевдо-код:

variables:
arraysize = root.count()
E[] inOrderNodeArray = new E[arraysize]
int index = 0

inorder traversal:
void inorder(Node n) {
    if (n) {
        inorder(n.left)
        inOrderNodeArray[index] = n
        index++
        inorder(n.right)
    }
}
Ответил 18/03/2011 в 14:01
источник пользователем

голоса
1

Хорошо, я думаю , что проблема использования вами «глобальной» переменной current. Как это установлено, не имеет особого смысла. Вам не нужно в любом случае, потому что «ток» Nodeявляется тот , который предусмотрен в параметрах.

Также следует рассмотреть вопрос о переименовании функции. Вы ничего не сортировать здесь, просто собирая содержимое дерева, так что имя , например , как collectбыло бы более подходящим.

public E[] toArray(E[] a) {
  Node n = root;
  a = collect(n, a);
  return a;
}

public E[] collect(Node n, E[] a) {

  if (n.left != null) {
    // If there is a left (smaller) value, we go there first
    collect(n.left, a);
  }


  // Once we've got all left (smaller) values we can
  // collect the value of out current Node.
  a[i] = n.obj;
  i++;

  if (n.right != null) {
    // And if there is a right (larger) value we get it next
    collect(n.right, a);
  }

  return a;
}

(Отказ от ответственности: я не проверял это)


Альтернативная реализация без глобального индекса:

public E[] toArray(E[] a) {
  Node n = root;
  collect(n, a, 0);
  return a;
}

public int collect(Node n, E[] a, int i) {

  if (n.left != null) {
    // If there is a left (smaller) value, we go there first
    i = collect(n.left, a, i);
  }


  // Once we've got all left (smaller) values we can
  // collect the value of out current Node.
  a[i] = n.obj;
  i++;

  if (n.right != null) {
    // And if there is a right (larger) value we get it next
    i = collect(n.right, a, i);
  }

  return i;
}
Ответил 18/03/2011 в 14:07
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more