Wie ein Array mit Knotenelementen aus einem binären Suchbaum, aufsteigend zu füllen?

stimmen
0

In einer Schulaufgabe Ich bin ein Verfahren vervollständigen soll, die ein Array von Knotenelementen in ascendig Ordnung zurückkehren. Die Knoten sind in einem binären Suchbaum zusammengebaut, so sie richtig zu sortieren, ich habe eine Spitze eine rekursive Methode zu erstellen, um die Arbeit zu erledigen.

Das Problem ist, dass diese noch nicht einmal alle Elemente in der Sammlung ergeben nach dem Testausgang (java.lang.AssertionError. ToArray () kehrt nicht alle Elemente in der Sammlung)

Ich konnte nicht mit irgendeiner anderen Weise komme mit dem Array zu tun, und ich bin mir nicht ganz sicher, ob die Rekursion auch funktioniert. Jede Hilfe ist sehr geschätzt. Unten ist mein 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

Testausgang:

java.lang.AssertionError: toArray () kehrt nicht alle Elemente in der Sammlung .: Testperson ( Bender) compareTo (Testperson ( Fry)) == 0 erwartet. wahr, aber war: false bei inf1010.assignment .IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:74) bei inf1010.assignment.IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:83) bei inf1010.assignment.IfiCollectionTest.assertCompareToEqualsNoOrder (IfiCollectionTest.java:100) bei 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);
}

Ich weiß nicht, ob ich mehr von dem Testcode schreiben sollte, es ist recht umfangreich, und es könnte ein wenig zu viel für einen Beitrag sein?

Veröffentlicht am 18/03/2011 um 13:02
quelle vom benutzer
In anderen Sprachen...                            


4 antworten

stimmen
0

Ich denke , wo Sie verwirrt sind , ist , dass , wenn Sie überprüfen, wie ein binärer Suchbaum funktioniert, ist , dass es immer sortiert ist. Sie beginnen an Ihrem Stammknoten, und dann , wie Sie einen neuen Knoten einzufügen, es fügt sie in die entsprechende Position (dh nach links oder rechts) in Abhängigkeit von den Werten. Sie sollten also nicht sortieren müssen rufen zu beginnen. Also ich würde dort beginnen, und lesen Sie auf binäre Suchbäume. Zum Beispiel Wikipedia hat einen guten Artikel.

Update: Ignorieren meines Kommentars Sie sollten das auch nicht tun müssen. Sagen Sie bitte einfügen 8, 3, 7, 9, 12, 2, 10, 1 in den Baum in dieser Reihenfolge. Es sollte aussehen wie dieses Ende:

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

Wenn man es betrachtet das heißt sie, um zu bekommen, an der Wurzel beginnen, dann, wenn es einen Knoten auf der linken Seite hat nach links bekam, wenn nicht, selbst wieder, und nach rechts gehen, wenn sie einen Wert hat. Die Wiederholung dieses für jeden Knoten auftreten.

Beantwortet am 18/03/2011 um 13:30
quelle vom benutzer

stimmen
1

Ich sehe Sie den Code haben

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

aber ich kann nicht scheinen, bei denen zu finden, zeigen Sie Strom zurück auf den aktuellen Knoten so eingestellt, dass, wenn Sie tun

a[i] = current.obj;

Sie bekommen das richtige Ergebnis. Das ist wahrscheinlich, warum Sie nicht alle Ergebnisse. Auf jeden Fall sehe ich nicht (zumindest aus den Codefragmenten haben Sie auf dem Laufenden) warum aktuellen Bedarf eine Klassenvariable sein und nicht nur in der Art Methode deklariert. Im Allgemeinen sollten Sie nicht mit Variablen Klasse sein, wenn Sie nicht wirklich brauchen sie.

Edit: Sie können entweder Strom zurück auf den Knoten festgelegt Sie verarbeiten nach Art auf dem linken Kind wie dieser Aufruf

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

Oder auch nicht Strom verbrauchen kann überhaupt in diesem Fall müßten Sie so etwas wie

if (n.left != null)
    sort(n.left, a);
a[i] = n.obj;
i++;
if (n.right != null)
    sort(n.right, a);
Beantwortet am 18/03/2011 um 13:57
quelle vom benutzer

stimmen
0

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

Der einfachste Weg zu tun, was Sie suchen, ist der Baum Inorder und hängen an einem Arraylist zu durchqueren. Um das Array Sie die .ToArray () -Methode des Arraylist aufrufen können.

Wenn Sie nicht eine Arraylist verwenden können, deklarieren einen Index und eine Anordnung außerhalb des inordertraversal und Zuwachs, müssen Sie wissen, wie viele Elemente in dem Baum sind Ihr Array zu deklarieren.

Pseudocode:

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)
    }
}
Beantwortet am 18/03/2011 um 14:01
quelle vom benutzer

stimmen
1

Ok, ich denke , das Problem ist die Nutzung des „global“ Variable current. Die Art und Weise festgelegt ist, macht nicht viel Sinn machen. Sie brauchen nicht zu wie auch immer, weil die „aktuelle“ Nodeist derjenige, der in den Parametern zur Verfügung gestellt wird.

Auch sollten Sie die Umbenennung Ihre Funktion prüfen. Sie sortieren hier nichts, nur den Inhalt des Baumes zu sammeln, so ein Name wie collectwäre besser geeignet.

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: Ich habe nicht getestet)


Alternative Implementierung ohne den globalen 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;
}
Beantwortet am 18/03/2011 um 14:07
quelle vom benutzer

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