Anzahl Knoten im Binären Baum

Neue Frage »

Auf diesen Beitrag antworten »
vickal93 Anzahl Knoten im Binären Baum

Meine Frage:
Ich hänge ziemlich an einer Methode, und zwar sollte man hier die Anzahl der Knoten berehcnen. Der vorgegebene Code ist:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
/** Binaerer Baum fuer Daten vom Typ INHALT */
public class BinaerBaum<INHALT> {
  /** Wurzel des Baumes */
  Knoten<INHALT> wurzel;

  /** Konstruktor fuer den Baum */
  public BinaerBaum(Knoten<INHALT> wurzel) {
    this.wurzel = wurzel;
  };

  /** Anzahl der Knoten zaehlen */
  public int anzahlKnoten() {
    // TODO: Implementieren
  }

  /** Hoehe berechnen */
  public int hoehe() {
    return hoehe(wurzel);
  }

  /** Rekursive Hoehe */
  private int hoehe(Knoten k) {
    if (k == null) {
      return 0;
    } else {
      return 1 + Math.max(hoehe(k.links), hoehe(k.rechts));
    }
  }

  /** Klasse, die einen Knoten des Baumes speichert */
  protected static class Knoten<INHALT> {
    /** Gespeichterte Daten */
    protected INHALT daten;

    /** Linker und rechter Sohn */
    protected Knoten<INHALT> links, rechts;

    /** Konstruktor fuer Knoten */
    public Knoten(INHALT daten, Knoten<INHALT> links, Knoten<INHALT> rechts) {
      this.daten = daten;
      this.links = links;
      this.rechts = rechts;
    }
  }

  /** Methode zum Testen der Implementierung - besser: JUnit Test */
  public static void main(String[] args) {
    Knoten<Integer> links = new Knoten<Integer>(1, null,
        new Knoten<Integer>(2, null, null));
    Knoten<Integer> rechts = new Knoten<Integer>(5,
        new Knoten<Integer>(4, null, null),
        new Knoten<Integer>(6, null,
          new Knoten<Integer>(7, null, null)));
    Knoten<Integer> wurzel = new Knoten<Integer>(3, links, rechts);
    BinaerBaum<Integer> baum = new BinaerBaum<Integer>(wurzel);
    System.out.println("Hat der Baum die Hoehe 4? " + baum.hoehe());
    BinaerBaum<Integer> leer = new BinaerBaum<Integer>(null);
    System.out.println("Hat der leere Baum die Hoehe 0? " + leer.hoehe());
    System.out.println("Hat der Baum 7 Knoten? " + baum.anzahlKnoten());
    System.out.println("Hat der leere Baum 0 Knoten? " + leer.anzahlKnoten());
  }
}


Meine Ideen:
Meine Idee war folgende:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
	Knoten<INHALT> links;
	Knoten<INHALT> rechts;

	/** Anzahl der Knoten zaehlen */
	public int anzahlKnoten() {
		int anzahl = 1;
		if (links != null)
			anzahl += links.anzahlKnoten();

		if (rechts != null)
			anzahl += rechts.anzahlKnoten();

		return anzahl;
	}


Jedoch gibt er mit statt 7 Knoten nur einen raus. An sich bearbeite ich das doch rekursiv, ich weiß deswegen nciht wo mein Fehler ist. unglücklich Bitte um Hilfe!
 
Auf diesen Beitrag antworten »
eulerscheZahl

Wenn du links und rechts vorher erst definierst und nicht initialisierst, sind die null.
Du musst bei der wurzel starten und davon den rechten und linken Knoten nehmen, nicht von neu erstellten Variablen.

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
public int anzahlKnoten() {
	return anzahlKnoten(wurzel);
}

public int anzahlKnoten(Knoten<INHALT> knoten) {
	int anzahl = 1;
	if (knoten.links != null)
		anzahl += anzahlKnoten(knoten.links);

	if (knoten.rechts != null)
		anzahl += anzahlKnoten(knoten.rechts);

	return anzahl;
}
Auf diesen Beitrag antworten »
vickal93

Ja, ursprünglich habe ich auch alles mögliche mit wurzel versucht...
Aber vielen Dank! Sehe ich das dann richtig, dass man diese Methode ohne einem Parameter nicht lösen kann, sondern eben eine Art Hilfsmethode braucht? (Auf diese Idee bin ich nämlich nicht gekommen. :hammersmile
Auf diesen Beitrag antworten »
eulerscheZahl

Irgendwo musst du die aktuelle Position speichern, wo du dich im Baum befindest und von welchem Knoten du die Kinder zählen willst.
Bei der Höhe hast du es ja auch auf die Weise gemacht.

PS: habe oben einen Fehler: wenn die wurzel null ist, gibt es bei mir eine Exception, die beim letzten Test auch ausgelöst wird.
 
Auf diesen Beitrag antworten »
vickal93

Ist mir auch grad aufgefallen, aber habe den Fehler in der anzahlKnoten() Methode beseitigt. smile Danke nochmal!
Auf diesen Beitrag antworten »
Batista

Ist der <INHALT> wichtig?
public int anzahlKnoten(Knoten<INHALT> knoten) {

kann man nicht auch
public int anzahlKnoten(Knoten knoten) { schreiben?
Auf diesen Beitrag antworten »
eulerscheZahl

Batista,
ich dachte, das hätten wir HIER geklärt?
Auf diesen Beitrag antworten »
Batista

Zitat:
Original von eulerscheZahl

du siehst, ich habe Integer und Float vermischt. Wenn du den generischen Typ angibst (also Knoten<INHALT>), funktioniert das nicht.
The method suche(Knoten<Integer>) in the type Knoten<Integer> is not applicable for the arguments (Knoten<Float>)

.


Hier sagst du doch Knoten<INHALT>) funktioniert nicht? aber genau das verwendest du hier?
Auf diesen Beitrag antworten »
eulerscheZahl

Bitte im Zusammenhang zitieren.
Der Codeausschnitt oberhalb des Zitats funktioniert bei Generics nicht mehr, und das ist genau der Sinn von Generics. Du kannst hier schon zur Compilezeit sicherstellen, dass nicht verschiedene Datentypen vermischt werden.
Auf diesen Beitrag antworten »
Batista

Ich dachte ich hätte es verstanden

Man hat den code

code
....
public int anzahlKnoten(Knoten<INHALT> knoten) {

... code


public static void main(String[] args) {
Knoten<Integer> k1 = new Knoten<Integer>(3, null, null);
Knoten<Float> k2 = new Knoten<Float>(3.2f, null, null);
k1.suche(k2);
}


würde
The method suche(Knoten<Integer>) in the type Knoten<Integer> is not applicable for the arguments (Knoten<Float>)
das liefern?
Auf diesen Beitrag antworten »
eulerscheZahl

Richtig, und genau das Verhalten ist gewünscht, wenn man will, dass entweder nur Ganzzahlen oder nur Gleitpunktzahlen im Baum stehen.
Und wenn ein anderer Programmierer deine Klasse verwendet, weist ihn bereits der Compiler in die Schranken, wenn er es doch versucht. Andernfalls könnte es zu einer RuntimeException führen, die der Programmierer vielleicht gar nicht entdeckt, sondern erst der Endanwender.
Auf diesen Beitrag antworten »
Batista

@eulerscheZahl
Kannst du bitte folgendes ansehen, und kurzes ja oder nein, ob die Methode richtig funktioniert ?
/** Anzahl der Knoten zaehlen */
public int anzahlKnoten() {
return anzahlKnoten(wurzel);
}
/** Rekursive anzahlKnoten */
private int anzahlKnoten(Knoten k){
if (k==null){
return 0;
}else{
return 1 + anzahlKnoten(k.links)+anzahlKnoten(k.rechts);
}
}
Auf diesen Beitrag antworten »
eulerscheZahl

Ich gebe dir ein ja Daumen hoch
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »