2 Stimmen

Umwandeln des binären Baums -> BST (Beibehaltung der ursprünglichen Baumstruktur)

Ich habe einen binären Baum von irgendeiner Form. Ich möchte ihn in einen BST-Suchbaum derselben Form umwandeln. Ist das möglich?

Ich habe Methoden ausprobiert wie -

  • Führen Sie eine Inorder-Durchquerung des binären Baums durch und legen Sie die Inhalte in ein Array. Kartieren Sie dies dann in einen BST und achten Sie dabei auf die Bedingung (linker Wert <= Wurzel <= rechter Wert). Dies funktioniert für einige Fälle, scheitert jedoch für andere.

Nachtrag: Ich habe mir das hier angesehen - Binäre Baumfrage. Überprüfung der ähnlichen Form. Aber es ist einfach, zwei BSTs auf Ähnlichkeit in Form zu vergleichen.

5voto

Niki Yoshiuchi Punkte 15805

Die kurze Antwort lautet: du kannst es nicht. Ein BST erfordert, dass die Knoten der Regel folgen: links <= aktuell < rechts. In dem Beispiel, auf das du verwiesen hast: http://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_tree.svg, wirst du feststellen, dass du keinen BST mit der gleichen Form bauen kannst.

Wenn du jedoch die Definition eines BST so dehnen möchtest, dass sie links <= aktuell <= rechts zulässt (beachte, dass hier aktuell <= rechts erlaubt ist, im Gegensatz zur strengeren Definition), kannst du das tun. Sortiere alle Elemente und füge sie in ein Array ein. Führe nun eine In-Order-Traversierung durch und ersetze die Werte an den Knoten mit jedem Element in deinem Array. Hier ist ein Pseudocode:

// t ist dein nicht-BST-Baum, a ist ein Array, das die sortierten Elemente von t enthält, i ist der aktuelle Index in a
Index i = 0
create_bst(Tree t, Array a)
{
  if(t ist NIL)
    return;
  create_bst(t->left, a)
  t->data = a[i]
  i++
  create_bst(t->right, a)
}

Das Ergebnis wird jedoch kein echter BST sein. Wenn du einen echten BST haben möchtest, der so nah wie möglich an der originalen Form ist, dann füge die Elemente erneut in einem sortierten Array ein, aber füge sie dieses Mal in einen BST ein. Die Reihenfolge, in der du sie einfügst, wird durch die Größen der Teilbäume des Originalbaums definiert. Hier ist ein Pseudocode:

// links wird zu Beginn auf 0 gesetzt
create_true_bst(Tree t, BST bt, Array a, Index links)
{
  Index i = links + größe_von_linkem_teilbaum(t)
  bt->einfügen(a[i])
  if (größe_von_linkem_teilbaum(t) != 0)
  {
    create_true_bst(t->left, bt, a, links)
    create_true_bst(t->right, bt, a, i + 1)
  }
}

Dies garantiert jedoch nicht, dass die Form gleich ist.

1voto

user3021620 Punkte 11

Extrahiere alle Elemente des Baumes, sortiere sie und verwende dann den rekursiven Inorder-Prozess, um Werte zu ersetzen.

0voto

Rex Kerr Punkte 164629

Die Methode, die Sie beschreiben, funktioniert garantiert, wenn Sie sie ordnungsgemäß implementieren. Die Traversierungsreihenfolge in einem binären Baum ist eindeutig und definiert eine Anordnung der Elemente. Wenn Sie die Elemente nach Wert sortieren und sie dann entsprechend dieser Reihenfolge einfügen, wird es immer wahr sein, dass

linker Teilbaum <= Wurzel <= rechter Teilbaum

für jeden Knoten, vorausgesetzt, dies ist die Reihenfolge, in der Sie sie durchlaufen, und vorausgesetzt, dass Sie sie in dieser Reihenfolge sortiert haben.

0 Stimmen

Ich habe das ausprobiert. Vielleicht mache ich einen einfachen Fehler. Nehmen wir den hier präsentierten Binärbaum - upload.wikimedia.org/wikipedia/commons/f/f7/Binary_tree.svg Nach dem Inorder-Durchlauf habe ich (2,7,5,6,11,2,5,4,9) als Array erhalten. Sollte man sie dann sortieren? Würde das nicht alles erhöhen? Und würde der BST dann nicht einfach zu einer verketteten Liste werden?

0 Stimmen

Sortiere, um (2,2,4,5,5,6,7,9,11) zu erhalten. Setze sie in der gleichen Reihenfolge wie im Baum zurück, d.h. 2->2, 7->2, 5->4, 6->5, 11->5, 2->6, 5->7, 4->9, 9->11. Dann sieht Ihr Baum wie folgt aus: 6,L(2,L(2),R(5,L(5),R(5))),R(9,L(7),R(11)).

0voto

Svante Punkte 49287

Ich würde einfach zwei Inorder-Traversierungen machen. Bei der ersten Traversierung die Werte aus dem Baum holen und in einen Heap einfügen. Bei der zweiten die Werte in der Reihenfolge aus dem Heap holen und in den Baum einfügen. Dies läuft in O(n·log n) Zeit und O(n) Platz.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X