Cómo llenar una matriz con elementos de nodo de un árbol de búsqueda binaria, en orden ascendente?

votos
0

En una tarea escolar supone que tengo que completar un método que debe devolver una matriz de elementos de nodo con el fin ascendig. Los nodos están montados en un árbol binario de búsqueda, por lo que ordenarlos correcta, tengo un consejo para crear un método recursivo para hacer el trabajo.

El problema es que esto ni siquiera dió todos los elementos de la colección de acuerdo con la salida de prueba (java.lang.AssertionError:. ToArray () no devuelve todos los elementos de la colección)

No podía llegar a cualquier otra forma de lidiar con la matriz, y no estoy muy seguro de si la recursividad aún funciona. Cualquier ayuda es muy apreciada. A continuación se muestra el código:

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

salida de prueba:

java.lang.AssertionError: toArray () no devuelve todos los elementos de la colección .: TestPerson ( Bender) compareTo (TestPerson ( Fry)) == 0 se esperaba:. cierto, pero era: falsa en inf1010.assignment .IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:74) en inf1010.assignment.IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:83) en inf1010.assignment.IfiCollectionTest.assertCompareToEqualsNoOrder (IfiCollectionTest.java:100) en 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);
}

No sé si debería publicar más del código de prueba, es bastante extensa, y que podría ser un poco demasiado para un puesto?

Publicado el 18/03/2011 a las 13:02
fuente por usuario
En otros idiomas...                            


4 respuestas

votos
0

Creo que cuando usted está confundido es que si se echa un vistazo a cómo funciona un árbol de búsqueda binario obras, es que siempre está ordenada. Usted comienza en el nodo raíz, y luego a medida que inserta un nuevo nodo, se inserta en la posición adecuada (es decir, hacia la izquierda o la derecha) en función de los valores. Por lo que no debería tener que llamar a una especie, para empezar. Así que me gustaría empezar por ahí, y leer sobre árboles binarios de búsqueda. Por ejemplo Wikipedia tiene un artículo decente.

Actualización: No haga caso de mi comentario que no es necesario hacer eso tampoco. Digamos que inserta 8, 3, 7, 9, 12, 2, 10, 1 en el árbol, en ese orden. Debe terminar pareciéndose a esto:

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

Si nos fijamos en lo que significa para conseguir el fin, empezar en la raíz, a continuación, si tiene un nodo a la izquierda llegamos a la izquierda, si no, volver en sí, y vaya a la derecha si tiene un valor. La repetición de este para cada nodo que encuentre.

Respondida el 18/03/2011 a las 13:30
fuente por usuario

votos
1

Veo que tiene el código

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

pero me parece que no puede encontrar en qué punto se establece vuelta actual en el nodo actual, de modo que cuando se hace

a[i] = current.obj;

se obtiene el resultado correcto. Probablemente por eso que no está recibiendo todos los resultados. En cualquier caso, no veo (al menos desde los fragmentos de código que has publicado) por qué las necesidades actuales para ser una variable de clase y no sólo declaran en el método de ordenación. En general, usted no debe estar usando variables de clase si no lo hace realmente los necesita.

Editar: Usted puede configurar ya sea corriente de vuelta al nodo que se está procesando después de llamar a una especie en el hijo izquierdo como esto

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

O no utilizar la corriente en absoluto, en cuyo caso tendría algo así como

if (n.left != null)
    sort(n.left, a);
a[i] = n.obj;
i++;
if (n.right != null)
    sort(n.right, a);
Respondida el 18/03/2011 a las 13:57
fuente por usuario

votos
0

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

La manera más fácil de hacer lo que busca es a recorrer el árbol finde y anexar a un ArrayList. Para obtener la matriz se puede llamar al método .toArray () de la arrayList.

Si no puede usar un ArrayList, declarar un índice y una matriz fuera del inordertraversal y el incremento, necesitará saber cuántos elementos hay en el árbol de declarar su matriz.

pseudo código:

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)
    }
}
Respondida el 18/03/2011 a las 14:01
fuente por usuario

votos
1

Ok, creo que el problema es el uso de la variable "global" current. La forma en que se establece, no tiene mucho sentido. No es necesario de todos modos, debido a que el "actual" Nodees el que se proporciona en los parámetros.

También debe tener en cuenta el cambio de nombre de su función. No está ordenando nada aquí, sólo la recogida de los contenidos del árbol, por lo que un nombre como collectsería más adecuado.

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

(Negación: No he probado esto)


implementación alternativa sin que el índice global:

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;
}
Respondida el 18/03/2011 a las 14:07
fuente por usuario

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