Comment remplir un tableau avec des éléments de noeud d'un arbre de recherche binaire, dans l'ordre croissant?

voix
0

Dans une mission de l'école, je suis censé compléter une méthode qui doit retourner un ensemble d'éléments de nœud dans l'ordre ascendig. Les noeuds sont assemblés dans un arbre binaire de recherche, afin de les trier correctement, je suis une astuce pour créer une méthode récursive pour faire le travail.

Le problème est que ce ne donne pas encore tous les éléments de la collection en fonction de la sortie de test (java.lang.AssertionError:. ToArray () ne retourne pas tous les éléments de la collection)

Je ne pouvais pas trouver une autre façon de traiter le tableau, et je ne suis pas tout à fait sûr si la récursion fonctionne même. Toute aide est très appréciée. Voici mon code:

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

Sortie test:

java.lang.AssertionError: toArray () ne retourne pas tous les éléments de la collection .: TestPerson ( Bender) compareTo (TestPerson ( Fry)) de == 0 attendu. vrai, mais était: faux à 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);
}

Je ne sais pas si je devrais poster plus du code de test, il est assez vaste, et il pourrait être un peu trop pour un poste?

Créé 18/03/2011 à 13:02
source utilisateur
Dans d'autres langues...                            


4 réponses

voix
0

Je pense que lorsque vous êtes confus est que si vous vérifiez comment fonctionne un arbre de recherche binaire, est qu'il est toujours triée. Vous commencez à votre nœud racine, puis que vous insérez un nouveau nœud, il insère dans la position appropriée (c. - à - gauche ou à droite) en fonction des valeurs. Donc , vous ne devriez pas avoir à appeler genre pour commencer. Donc , je commencerais là - bas, et de lire sur les arbres binaires de recherche. Par exemple wikipedia a un article décent.

Mise à jour: Ignorer mon commentaire que vous ne devriez pas avoir à le faire non plus. Dites insertion 8, 3, 7, 9, 12, 2, 10, 1 dans l'arbre dans cet ordre. Il devrait finir par ressembler à ceci:

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

Si vous regardez cela signifie pour les obtenir dans l'ordre, commencer à la racine, puis si elle a un noeud à la gauche a obtenu à gauche, sinon, se retourner et aller à droite si elle a une valeur. La répétition de ce pour chaque nœud que vous rencontrez.

Créé 18/03/2011 à 13:30
source utilisateur

voix
1

Je vois que vous avez le code

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

mais je ne peux pas sembler trouver à quel point vous retardera en cours au niveau du noeud courant de sorte que lorsque vous faites

a[i] = current.obj;

vous obtenez le bon résultat. C'est probablement la raison pour laquelle vous n'êtes pas obtenir tous les résultats. En tout cas, je ne vois pas (au moins des fragments de code que vous avez posté) pourquoi les besoins actuels comme une variable de classe et non seulement déclarés dans la méthode de tri. En général, vous ne devriez pas utiliser des variables de classe si vous n'avez pas vraiment besoin.

Edit: Vous pouvez régler en cours sur le nœud que vous traitez après avoir appelé tri sur l'enfant gauche comme celui - ci

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

Ou pas utiliser courant du tout dans ce cas, vous auriez quelque chose comme

if (n.left != null)
    sort(n.left, a);
a[i] = n.obj;
i++;
if (n.right != null)
    sort(n.right, a);
Créé 18/03/2011 à 13:57
source utilisateur

voix
0

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

La meilleure façon de faire ce que vous recherchez est de traverser l'arbre afinde et ajouter à une liste de tableaux. Pour obtenir le tableau, vous pouvez appeler la méthode .toArray () du arrayList.

Si vous ne pouvez pas utiliser un arraylist, déclarer un index et un tableau en dehors de la inordertraversal et l'incrément, vous aurez besoin de savoir combien d'éléments sont dans l'arbre de déclarer votre tableau.

pseudo-code:

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)
    }
}
Créé 18/03/2011 à 14:01
source utilisateur

voix
1

Ok, je pense que le problème est votre utilisation de la variable « globale » current. La façon dont il est défini, ne fait pas beaucoup de sens. Vous n'avez pas besoin de toute façon, parce que le « courant » Nodeest celui qui est prévu dans les paramètres.

Aussi , vous devriez penser à renommer votre fonction. Vous n'êtes pas triez quoi que ce soit ici, juste recueillir le contenu de l'arbre, donc un nom tel que collectserait plus approprié.

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

(Disclaimer: Je n'ai pas testé)


la mise en œuvre sans l'autre indice 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;
}
Créé 18/03/2011 à 14:07
source utilisateur

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