Hoe maak je een array met knooppunt elementen van een binaire zoekboom, in oplopende volgorde te vullen?

stemmen
0

In een schoolopdracht ik moet een methode die een array van knooppunt elementen moeten terugkeren in ascendig bestelling af te ronden. De knooppunten worden geassembleerd in een binaire zoekboom, dus om ze te sorteren correct, ik heb een tip om een ​​recursieve methode om het werk te doen maken.

Het probleem is dat alle elementen van de verzameling niet eens bereid volgens testuitgang (java.lang.AssertionError. ToArray () niet alle elementen in de collectie terug)

Ik kon niet komen met een andere manier om te gaan met de serie, en ik ben niet helemaal zeker of de recursie werkt zelfs. Alle hulp wordt zeer gewaardeerd. Hieronder is mijn 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

Test output:

java.lang.AssertionError: toArray () niet alle elementen terug te keren in de collectie .: proefpersoon ( Bender) compareTo (proefpersoon ( Fry)) == 0 verwacht:. true, maar was: vals bij inf1010.assignment .IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:74) bij inf1010.assignment.IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:83) bij inf1010.assignment.IfiCollectionTest.assertCompareToEqualsNoOrder (IfiCollectionTest.java:100) bij 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);
}

Ik weet niet of ik meer van de test code moet plaatsen, het is vrij uitgebreid, en het misschien een beetje te veel voor een post zijn?

De vraag is gesteld op 18/03/2011 om 13:02
bron van user
In andere talen...                            


4 antwoorden

stemmen
0

Ik denk dat wanneer je in de war is dat als je nagaan hoe een binaire zoekboom werken, is dat het altijd wordt gesorteerd. U begint op uw root-knooppunt, en dan als je een nieuw knooppunt invoegt, voegt het in de juiste positie (dat wil zeggen naar links of rechts), afhankelijk van de waarden. Dus moet je niet te bellen soort om mee te beginnen. Dus ik zou daar beginnen, en lees over binary search bomen. Bijvoorbeeld wikipedia heeft een fatsoenlijke artikel.

Update: Negeer mijn commentaar moet je niet nodig hebt om dat ook te doen. Zeg u invoegt 8, 3, 7, 9, 12, 2, 10, 1 in de boom in die volgorde. Het moet uiteindelijk uitzien als dit:

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

Als je kijkt naar het op die voor hen betekent op orde te krijgen, te beginnen bij de wortel, dan als het een knooppunt naar links kreeg aan de linkerkant, zo niet, het vertrek zelf, en ga naar de rechter als het een waarde. Het herhalen van deze voor elk knooppunt die je tegenkomt.

antwoordde op 18/03/2011 om 13:30
bron van user

stemmen
1

Ik zie dat je de code

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

maar ik kan niet lijken te vinden op welk punt je huidige terug op het huidige knooppunt zo instellen dat als je dat doet

a[i] = current.obj;

je krijgt het juiste resultaat. Dat is waarschijnlijk de reden waarom je niet alle resultaten krijgt. In ieder geval zie ik niet (althans van de code fragmenten waarin je gepost hebt) waarom de huidige behoeften tot een klasse variabele en niet alleen verklaard in het soort methode. In het algemeen moet je niet met behulp van de klasse variabelen als je niet echt nodig.

Edit: U kunt instellen huidige terug naar het knooppunt dat u verwerking na het aanroepen van een soort aan de linkerkant kind als deze

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

Of niet actueel gebruikt op alle in dat geval zou je zoiets hebben

if (n.left != null)
    sort(n.left, a);
a[i] = n.obj;
i++;
if (n.right != null)
    sort(n.right, a);
antwoordde op 18/03/2011 om 13:57
bron van user

stemmen
0

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

De eenvoudigste manier om te doen wat je zoekt is om de boom inorder doorkruisen en toe te voegen aan een ArrayList. Om de array kunt u de methode .toArray () van de ArrayList bellen krijgen.

Als u een arraylist niet kunt gebruiken, verklaren een index en een reeks buiten de inordertraversal en increment, moet u weten hoeveel elementen in de boom om uw array verklaren.

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)
    }
}
antwoordde op 18/03/2011 om 14:01
bron van user

stemmen
1

Ok, ik denk dat het probleem is het gebruik van de "globale" variabele current. De manier waarop het is ingesteld, niet veel zin te maken. U hoeft niet om hoe dan ook, omdat de "huidige" Nodeis degene die is voorzien in de parameters.

Ook moet u overwegen het hernoemen van uw functie. U bent hier niets sorteren, alleen het verzamelen van de inhoud van de boom, dus een naam als collectzou meer geschikt.

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: Ik heb dit niet getest)


Alternatieve implementatie zonder de globale index:

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;
}
antwoordde op 18/03/2011 om 14:07
bron van user

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