Hvordan fylle en matrise med knuteelementer fra et binært søketre, i stigende rekkefølge?

stemmer
0

I en skoleoppgave jeg skal fullføre en metode som skal returnere en rekke knuteelementer i ascendig rekkefølge. Nodene er samlet i et binært søketre, så å sortere dem riktig, fikk jeg et tips for å lage en rekursiv metode for å gjøre jobben.

Problemet er at dette ikke engang gir alle elementene i samlingen i henhold til testutgangen (java.lang.AssertionError:. ToArray () returnerer ikke alle elementene i samlingen)

Jeg kunne ikke komme opp med noen annen måte å forholde seg til rekken, og jeg er ikke helt sikker på om rekursjon selv arbeider. Alle hjelpe er verdsatt. Nedenfor er min kode:

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 utgang:

java.lang.AssertionError: toArray () returnerer ikke alle elementene i samlingen .: TestPerson ( Bender) compareTo (TestPerson ( Fry)) == 0 forventet. sant, men var: falsk på inf1010.assignment .IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:74) ved inf1010.assignment.IfiCollectionTest.assertCompareToEquals (IfiCollectionTest.java:83) ved inf1010.assignment.IfiCollectionTest.assertCompareToEqualsNoOrder (IfiCollectionTest.java:100) ved 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);
}

Jeg vet ikke om jeg skulle legge mer av test kode, det er ganske omfattende, og det kan være litt for mye for ett innlegg?

Publisert på 18/03/2011 klokken 12:02
kilden bruker
På andre språk...                            


4 svar

stemmer
0

Jeg tror der du er forvirret er at hvis du sjekker ut hvordan en binært søketre fungerer, er at det alltid er sortert. Du starter på root node, og deretter som du setter inn en ny node, setter det inn i riktig stilling (dvs. mot venstre eller høyre) avhengig av verdiene. Så du skal ikke behøve å ringe liksom å begynne med. Så jeg ville begynne der, og les deg opp på binære søketrær. For eksempel wikipedia har en grei artikkel.

Oppdatering: Ignorer min kommentar du bør ikke trenger å gjøre det heller. Si du setter 8, 3, 7, 9, 12, 2, 10, 1 inn i treet i denne rekkefølge. Det skulle ende opp som ser slik ut:

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

Hvis du ser på det som betyr å få dem i rekkefølge, start ved roten, så hvis det har en node til venstre fikk til venstre, hvis ikke, gå tilbake i seg selv, og gå til høyre hvis det har en verdi. Gjenta dette for hver node du møter.

Svarte 18/03/2011 kl. 12:30
kilden bruker

stemmer
1

Jeg ser du har koden

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

men jeg kan ikke synes å finne noe som medførte du setter strøm tilbake på dagens node, slik at når du gjør

a[i] = current.obj;

du får riktig resultat. Det er nok derfor du ikke får alle resultatene. I alle fall ser jeg ikke (i hvert fall fra kodefragmenter har du postet) hvorfor dagens behov for å være en klassevariabel og ikke bare erklært i sorteringsmetode. Generelt bør du ikke skal bruke klassevariabler hvis du ikke virkelig trenger dem.

Edit: Du kan enten sette strømmen tilbake til noden du behandler etter ringer slag på venstre barnet som dette

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

Eller ikke bruke strøm i det hele tatt i så fall ville ha noe sånt

if (n.left != null)
    sort(n.left, a);
a[i] = n.obj;
i++;
if (n.right != null)
    sort(n.right, a);
Svarte 18/03/2011 kl. 12:57
kilden bruker

stemmer
0

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

Den enkleste måten å gjøre det du er ute etter er å traversere treet inorder og legge til en Arraylist. For å få matrisen kan du ringe .toArray () metoden i Arraylist.

Hvis du ikke kan bruke en Arraylist, erklærer en indeks og en rekke utenfor inordertraversal og tilvekst, må du vite hvor mange elementer er i treet for å erklære din array.

pseudo-kode:

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)
    }
}
Svarte 18/03/2011 kl. 13:01
kilden bruker

stemmer
1

Ok, jeg tror problemet er din bruk av "global" variable current. Måten det er satt, ikke mye mening. Du trenger ikke å uansett, fordi "dagens" Nodeer den som er gitt i parametrene.

Også du bør vurdere å døpe din funksjon. Du er ikke sortering noe her, bare samle innholdet i treet, så et navn som collectville være mer egnet.

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: Jeg har ikke testet dette)


Alternativ gjennomføring uten den globale indeksen:

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;
}
Svarte 18/03/2011 kl. 13:07
kilden bruker

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