Binärbaum auf Vollständigkeit prüfen

Status
Nicht offen für weitere Antworten.
B

Bernd1983

Gast
hallo, ich möchte einen Binärbaum auf Vollständigkeit prüfen.

Brainstorming:

Baum ist vollständig, wenn alle Blätter selbe Höhe aufweisen.

also eigentlich wenn die Höhe von links und rechts gleich ist.

Rückgabewert soll bool sein.


bei der Implementierung bekomm ichs nicht ganz gebacken

Bitte um Ratschläge
 

SnooP

Top Contributor
Also die Methode soll sein: boolean isVollständig()?
Kannst du da nicht über die Anzahl der Knoten % 2 != 0 gehen? .. war nur grad son Gedanke...
Ansonsten müsstest du den Baum durchwandern bis zu den Blättern und die höhe halt ermitteln ;)
 

Ilja

Bekanntes Mitglied
ganz einfach:

ich gehe davon aus, dass der baum mit verketteten listen implementiert ist?

wenn ja, dann schreibe eine rekursive funktion, die von jedem knoten ausgehend seine beiden unterknoten nacheinander besucht und deren höhe sein, falls der teilbaum volständig ist! anderenfalls false und abbrechen!

die blätter, da die ja keine unterknoten haben, geben 1 zurück und die aufrufende rekursion addiert falls recht-links beides = 1 ist 1 dazu und gibt somit 2 zurück...
die vorangehende rekursion muß also die zurückgegebene höhe der beiden unterzweige vergleichen und dann 1 dazu addieren.... usw.
 
B

Bernd1983

Gast
also ich habs ja so gemacht:

einfach mal die Höhe ermittelt:

Code:
int Baumtiefe(){
	  	
	  	return Baumtiefe(root);
	  }

	 int Baumtiefe(Node p){
	 	int links,rechts;
	 	if(p==null){
	 	return 0;
	 	}else{
	 		links=Baumtiefe(p.left);
	 		rechts=Baumtiefe(p.right);
	 	
	 	if(links>rechts){
	 		return links+1;}
	 	else{return rechts+1;}
	 }


ja aber wie prüfe ich da mit boolean, ob rechts und links gleich sind?
 

Ilja

Bekanntes Mitglied
in welcher form liegt der baum vor? wie bekommst du den?
was ist über den baum bekannt? anzahl der knoten, blätter?
 
B

Bernd1983

Gast
so:

class Node{

Node left;
Node right;
int val;
Node(int val){
this.val=val;
}

}//class Node

class Tree{

Node root;

methoden.......
 

Ilja

Bekanntes Mitglied
Code:
boolean istVollständig(Node root) {
  // falls beide teilzweige gleich-tief sind und insich vollständig (>=0)
  if(Baumtiefe(root.left) != -1 && Baumtiefe(root.right) == Baumtiefe(root.left))
    return true;
  else
    return false;
}

int Baumtiefe(Node knoten) {
  int links,rechts;
  // wenn Blatt, dann tiefe 0
  if(knoten.val == NULL) return 0;
  links = Baumtiefe(knoten.left);
  if(links >= 0) {
    rechts = Baumtiefe(knoten.right);
    if(rechts != -1 && links == rechts)
      // links-rechts gleich-tief -> return tiefe+1
      return links+1;
    else
      // links-rechts ist unterschiedlich tief!
      return -1;
  } else return -1;
}
 

Leroy42

Top Contributor
:shock: Warum nicht einfach
Code:
boolean istVollständig() {
  return links==null ? rechts==null : rechts != null && links.istVollständig() && rechts.istVollständig()
}
 
B

Bernd1983

Gast
he danke funktioniert klasse


ich wäre selber nie drauf gekommen.

@ilja,leroy bzw alle: gibt es eine Art "algo" wie man solche rekursiven Schritt für Schritt lößt. ich weiß ja wie die rekursion abläuft nur fehlt es mir schwer Algos dafür zu schreiben.

lg

bernd
 

Andre_

Mitglied
also Leroy42's Lösung ist FALSCH da sie auch vollständig liefert wenn rechts ein vollständiger Baum hängt und links ein Blatt .. dann ist er aber nicht vollständig...
Was er testet ist ob ein Binärbaum voll, d.h. jeder innere Knoten hat zwei Kindknoten.

Ilja hat genau diesen Test nicht drin :) sein Algorithmus funktioniert wenn der Baum voll ist....


Ich habe jetzt mal beide gemixt und den code ein wenig gestraft!!
Das Rekursionsende ist jetzt wenn kein Knoten übgergeben wird, d.h. bei einem Blatt bei beiden und wenn ein innerknoten eventuell nur ein Kind hat.


Code:
private static final int NICHT_VOLLSTAENDIG = -1;

boolean istVollständig(Node root) {
    return (Baumtiefe(root) != NICHT_VOLLSTAENDIG);
}

int Baumtiefe(Node knoten) {
  int links,rechts;
 
 // kein Knoten ... tiefe 0
  if(knoten == NULL) 
     return 0;

  links = Baumtiefe(knoten.left);
  if(links != NICHT_VOLLSTAENDIG) {
    rechts = Baumtiefe(knoten.right);
    if(links == rechts) 
      return links+1; // links-rechts gleich-tief -> return tiefe+1
  }
      
  return NICHT_VOLLSTAENDIG;

}
 

Leroy42

Top Contributor
Andre_ hat gesagt.:
also Leroy42's Lösung ist FALSCH da sie auch vollständig liefert wenn rechts ein vollständiger Baum hängt und links ein Blatt .. dann ist er aber nicht vollständig...
Was er testet ist ob ein Binärbaum voll, d.h. jeder innere Knoten hat zwei Kindknoten.

:shock: Stimmt! :shock:

Da fällt mir die süffisante Bemerkung meines ehemaligen Profs ein:

ExProf hat gesagt.:
Ihre (Problem-)Lösung ist wirklich sehr effizient!
Nur leider nicht effektiv...
 

Andre_

Mitglied
Algorithmus entwerfen:

Bernd1983 hat gesagt.:
Brainstorming:

Baum ist vollständig, wenn alle Blätter selbe Höhe aufweisen.

also eigentlich wenn die Höhe von links und rechts gleich ist.

Soweit schon richtig nur fehlt noch die Bedingung:

und die beiden Teilbäume auch vollständig sind.



Code:
int Baumhöhe(Knoten knoten)
{

   if (knoten == null) return 0; // Abbruchbedingung

   int links = baumhöhe(knoten.links);
   int rechts = baumhöhe(knoten.rechts);

  return Math.max(links,rechts)+1;
}

boolean istVollständig(Knoten wurzel)
{
   if ( wurzel == null) return true; //wenn kein knoten dann ist der Vollständig :)

   boolean antwort;
   antwort = (Baumhöhe(wurzel.links) == Baumhöhe(wurzel.rechts));
   antwort = antwort && istVollständig(wurzel.links);
   antwort = antwort && istVollständig(wurzel.rechts);
   return antwort;
}

Dieser Code würde jetzt genau das selbe liefern wie der im Beiträg obendrüber ist nur nicht so effizent, ist aber die genaue Umsetzung des Brainstorming! (Baumtiefe berechnet auch wirklich die Baumtiefe :) )

Da man jetzt aber die Tiefe der Teilbäume ziemlich häufig doppelt berechnet könnte man sich jetzt überlegen ob man das verbessern könnte!! Allerdings ist der Code oben sehr intuitiv und leicht wartbar was bei größeren Projekten auch einen wichtigen Stellenwert hat.

Das Problem wenn ich beide Funktionen in eine Packen will ist das ich zwei Sachen zurückgeben muss, einmal die Tiefe und einmal ob der Teilbaum vollständig ist. Dieses Problem haben wir in dem Code oben gelöst, indem wir den Tiefenwert missbraucht haben und ihn um ein Flag für den Status, ob er Vollständig ist, erweitert haben.

Man könnte jetzt genausogut dem Knoten um eine Variable Tiefe bzw. vollständig erweitern.

Code:
class Knoten {
Knoten links;
Knoten rechts;
Object value;
transient int tiefe;  //transient gibt an das der Wert nicht immer aktuell ist 
}

boolean istVollständig(Knoten wurzel)
{
    if ( wurzel == null) return true; //wenn kein knoten dann ist der Vollständig :)

   //zwingend vor der Tiefeberechnung weil diese sonst noch nicht auf die darunterliegenden Knoten ausgeführt wurde
   boolean antwort = istVollständig(wurzel.links) &&  istVollständig(wurzel.rechts);

   // aus dem wird jetzt der Code unten 
   //if (knoten == null) return 0; // Abbruchbedingung
   //
   //int links = baumhöhe(knoten.links);
   //int rechts = baumhöhe(knoten.rechts);
   //
   //return Math.max(links,rechts)+1;
   if (antwort) {
     wurzel.tiefe = 0;
     if (wurzel.links != null)  wurzel.tiefe = Math.max(wurzel.tiefe,wurzel.links);
     if (wurzel.rechts != null) wurzel.tiefe = Math.max(wurzel.tiefe,wurzel.rechts);
     wurzel.tiefe++;
   }

   return antwort;
}

Das ist jetzt nur ein Weg es gibt da sehr viele Möglichkeiten wie man das realisieren will... ein schönes Zitat über objektorientiertes Programmieren dazu

"There are thousand ways to skin the cat"

noch ein paar Tipps:
Übringens kapselt die Zeile boolean antwort = istVollständig(wurzel.links) && istVollständig(wurzel.rechts); eine If-Abfrage ... wenn wurzel.links schon nicht vollständig ist dann wird wurzel.rechts nicht berechnet ..

Wenn man richtig Objektorientiert programmieren will würde man die Funktion istVollständig an den Knoten hängen und nicht ihr einen Knoten übergeben ...

Man sollte eigentlich auch keine Umlaute in Variablennamen stecken .. ich habe es aber jetzt mal der besseren Lesbarkeit trotzdem getan ;)
 
B

Bernd1983

Gast
@Andre

also ich verstehe nicht warum der code von @ilja falsch sein soll. wenn die inneren Koten nicht vollständig sind liefert er false und wenn die Tiefe aller Blätter nicht gleich ist liefert er false.???

lg

bernd
 

Andre_

Mitglied
wenn der Knoten ein inner Knoten ist aber nur einen Kindknoten hat dann bekommst du da eine NullpointerException...

Beispiel knoten.left = null, knoten.right=irgendein Knoten;

Ilja hat gesagt.:
Code:
int Baumtiefe(Node knoten) {
  int links,rechts;
  // wenn Blatt, dann tiefe 0
  if(knoten.val == NULL) return 0; <---- knoten ist hier null -> null.val -> exception 
  links = Baumtiefe(knoten.left); <---- Hier wirst du dann Baumtiefe(null) aufrufen!! dann kommst du im nächsten durchlauf zu der Zeile obendrüber
  if(links >= 0) {
    rechts = Baumtiefe(knoten.right);
    if(rechts != -1 && links == rechts)
      // links-rechts gleich-tief -> return tiefe+1
      return links+1;
    else
      // links-rechts ist unterschiedlich tief!
      return -1;
  } else return -1;
}
 
B

Bernd1983

Gast
versteh ich nicht ganz zb t ist mein Baum

t.insert(10);
t.insert(5);
t.insert(3);
t.insert(2);
t.insert(4); - links

t.insert(15);
t.insert(13);
t.insert(11);
t.insert(14);
t.insert(17);
t.insert(16);
t.insert(18); - rechts

koten (5) ist ein innerer Knoten und der rechte Nachfolger ist null. bekomme klarerweise false und keine exception


Tut mir leid, aber ich verstehe das nicht wie du das meinst.??
 

Andre_

Mitglied
hmm musst du mal den ganzen Code hier posten oder mir per pn schicken ... oder lädst es irgendwo hoch und schickst mir den link..

Gruß André
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Y Wie greift man auf die Knoten in einem Binärbaum zu? Java Basics - Anfänger-Themen 5
T Binärbaum-Suche Implementation Java Basics - Anfänger-Themen 6
A Binärbaum rekursiv durchsuchen und Referenz zurückgeben Java Basics - Anfänger-Themen 4
D Werte aus einem BinärBaum in einem Array speichern Java Basics - Anfänger-Themen 1
D Binärbaum Blätter finden und Ausgeben Java Basics - Anfänger-Themen 22
O BinärBaum einfügen Java Basics - Anfänger-Themen 13
E Erste Schritte Testklasse Binärbaum Java Basics - Anfänger-Themen 10
void19 Methoden Binärbaum Inorder Traversierung in Array speichern Java Basics - Anfänger-Themen 1
A Größten Eintrag aus Binärbaum löschen Java Basics - Anfänger-Themen 4
L Ganzen BinärBaum ausgeben? Java Basics - Anfänger-Themen 3
L Binärbaum (Stammbaum) Java Basics - Anfänger-Themen 8
S Binärbaum in PreOrder in ArrayList speichern Java Basics - Anfänger-Themen 0
J Methoden Binärbaum, Traversierung in Array speichern Java Basics - Anfänger-Themen 18
K BinärBaum Java Basics - Anfänger-Themen 4
J Max. Anzahl von Knoten im Binärbaum Java Basics - Anfänger-Themen 3
M Werte der Knoten in Binärbaum addieren (iterativ) Java Basics - Anfänger-Themen 6
C Binärbaum mit grafischer Ausgabe Java Basics - Anfänger-Themen 0
J Binärbaum formatiert ausgeben. Java Basics - Anfänger-Themen 7
P Listen sortieren mit Binärbaum gibt keine Ausgabe ab 10000 Integern Java Basics - Anfänger-Themen 14
E Binärbaum - von rekursiv zu iterativ Java Basics - Anfänger-Themen 10
W Größtes Element im unsortierten Binärbaum Java Basics - Anfänger-Themen 7
N Generischer Binärbaum - löschen Java Basics - Anfänger-Themen 1
M Binärbaum mit parent-Zeigern Java Basics - Anfänger-Themen 1
B Methoden BinärBaum als String Knoten löschen Java Basics - Anfänger-Themen 5
S Binärbaum kopieren Java Basics - Anfänger-Themen 6
B Binärbaum mit java implementieren! Java Basics - Anfänger-Themen 5
D Binärbaum Suche Java Basics - Anfänger-Themen 5
D Binärbaum probleme Java Basics - Anfänger-Themen 4
P Binärbaum - Primärschlüssel Java Basics - Anfänger-Themen 3
X Fehler Binärbaum Java Basics - Anfänger-Themen 6
PaulG Fragen zu Binärbaum Java Basics - Anfänger-Themen 21
N Binärbaum/Implementierung Java Basics - Anfänger-Themen 9
P Binärbaum Ordnungsproblem Java Basics - Anfänger-Themen 8
P Generischer Binärbaum (compareTo Frage) Java Basics - Anfänger-Themen 4
P einen binärbaum implementieren Java Basics - Anfänger-Themen 4
M Binärbaum - Problem bei Knoten anhängen / löschen Java Basics - Anfänger-Themen 5
B Binärbaum höhe herausfinden Java Basics - Anfänger-Themen 12
L Rot Scharz Baum von Binärbaum erben Java Basics - Anfänger-Themen 9
S Klassen Aufgabe: Binärbaum überprüfen Java Basics - Anfänger-Themen 16
S Binärbaum Java Basics - Anfänger-Themen 9
S Variable Parameterliste in Binärbaum Java Basics - Anfänger-Themen 2
N BinärBaum Hilfestellung Java Basics - Anfänger-Themen 8
S Binärbaum prüfen, ob sortiert oder unsortiert Java Basics - Anfänger-Themen 6
W Binärbaum zahlen addieren Java Basics - Anfänger-Themen 7
S Binärbaum - Klasse Knoten - Methode Suchen Java Basics - Anfänger-Themen 5
S Binärbaum Java Basics - Anfänger-Themen 7
I Binärbaum Java Basics - Anfänger-Themen 5
S Bitte um Hilfe beim unsortierten Binärbaum!! Java Basics - Anfänger-Themen 6
J Binärbaum getSize Java Basics - Anfänger-Themen 4
P Fragen zum Binärbaum Java Basics - Anfänger-Themen 3
S Binärbaum implementieren Java Basics - Anfänger-Themen 6
K Tiefe im Binärbaum Java Basics - Anfänger-Themen 2
G generischer binärbaum Java Basics - Anfänger-Themen 9
G Binärbaum und Wrapperklassen Java Basics - Anfänger-Themen 6
F Binärbaum codieren. Codeproblem! Java Basics - Anfänger-Themen 4
D rekursion im binärbaum Java Basics - Anfänger-Themen 11
0 Binärbaum als verkettete Liste Java Basics - Anfänger-Themen 3
T Binärbaum - noch ein "klitzekleiner Fehler" Java Basics - Anfänger-Themen 4
G Frage zur einfügen in einem Binärbaum Java Basics - Anfänger-Themen 21
G Binärbaum grafisch darstellen Java Basics - Anfänger-Themen 4
D Wie kann man in Java nach Arrays auf Duplikate prüfen Java Basics - Anfänger-Themen 12
J Schlüsselworte Prüfen, ob ein bestimmtes, ganzes Wort in einem String enthalten ist. Java Basics - Anfänger-Themen 6
Ostkreuz Int Scanner auf Enter Eingabe prüfen Java Basics - Anfänger-Themen 4
S Prüfen ob ein zweidimensionales Array rechteckig ist Java Basics - Anfänger-Themen 4
M Prüfen on eine Zahl im String enthalten ist Java Basics - Anfänger-Themen 3
ravenz Schleife mit for über String Array „zahlen“und prüfen ob Wert „a“ oder „b“ oder „c“ entspricht (mittels || ) Java Basics - Anfänger-Themen 4
Fiedelbambu Prüfen von Komma stelle beim Taschenrechner Java Basics - Anfänger-Themen 5
sserio Prüfen, ob eine Zahl eine periodische Zahl ist Java Basics - Anfänger-Themen 20
I Auf vollen Monat prüfen? Java Basics - Anfänger-Themen 22
A Dateiname auf Vorkommen prüfen Java Basics - Anfänger-Themen 29
I Prüfen, ob Anzahl an Monate ein Jahr ergeben Java Basics - Anfänger-Themen 4
K Warum gibt mir z. B. 40^128 eine Zahl? Ich dachte mit xor kann man nur booleanwerte erhalten, also prüfen ob etwas whar oder falsch ist? Java Basics - Anfänger-Themen 1
W Klasse existiert prüfen Java Basics - Anfänger-Themen 5
Q Prüfen ob Zahl als Summe von Potenzen dargestellt werden kann. Java Basics - Anfänger-Themen 20
U Kann man bei Java gleich mehrere Bedingungen prüfen in der If, aber in einem "Satz"? Java Basics - Anfänger-Themen 1
O Ich ahbe einen char und diesen soll ich bei .matches prüfen, also ob der char in meiner Zeichenkette vorhanden ist, wie mache ich das? Java Basics - Anfänger-Themen 9
B Array nach Wert prüfen rekursiv Java Basics - Anfänger-Themen 5
G Strings auf Gleichheit prüfen - Aufgabe vom Prof. Java Basics - Anfänger-Themen 5
M Array auf Primzahlen prüfen Java Basics - Anfänger-Themen 7
K Wie String prüfen ob drei mal das gleiche Zeichen vorkommt? Java Basics - Anfänger-Themen 7
J ArrayList auf bereits vorhanden eintrag prüfen Java Basics - Anfänger-Themen 5
X Zwei Dimensionales Array prüfen Java Basics - Anfänger-Themen 1
B Prüfen, ob Zeit Überschreitung Java Basics - Anfänger-Themen 2
B Sudoku prüfen Java Basics - Anfänger-Themen 13
M Prüfen auf null ohne NPE Java Basics - Anfänger-Themen 1
X Array auf Leerstellen prüfen Java Basics - Anfänger-Themen 1
FelixN Prüfen, ob ein 2D-Array rechteckig ist Java Basics - Anfänger-Themen 42
C Erste Schritte JComboBox Einträge auf Duplikat prüfen Java Basics - Anfänger-Themen 4
M prüfen ob alle array werte gleich sind Java Basics - Anfänger-Themen 27
C Array auf Null-Inhalte prüfen Java Basics - Anfänger-Themen 9
B Prüfen, ob Country Code in Europa ist? Java Basics - Anfänger-Themen 24
L Prüfen ob Fax (Tif-Datei) vollständig angekommen ist Java Basics - Anfänger-Themen 15
O Datenstruktur auf SET prüfen in O(n) Java Basics - Anfänger-Themen 32
O Einzelne Bits umwandeln und prüfen Java Basics - Anfänger-Themen 23
U Mehrfacheingabe auf bestimmte Parameter prüfen Java Basics - Anfänger-Themen 8
B Prüfen, ob Datum2 der gleiche Tag ist wie Datum1 Java Basics - Anfänger-Themen 10
Dimax Erste Schritte String Eingabe Prüfen Java Basics - Anfänger-Themen 11
S char auf buchstabe/zeichen prüfen Java Basics - Anfänger-Themen 1
S Array doppelter Wert prüfen Java Basics - Anfänger-Themen 7
B Prüfen, ob es schon einen Termin gibt in einem Zeitraum Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben