Binärbaum visualisieren auf Terminal

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
duffy6
User
Beiträge: 3
Registriert: Donnerstag 7. April 2022, 16:10

Hallo zusammen,

ich habe mir diesen Binärbaum hier mal angesehen und damit rumgespielt:

https://www.techiedelight.com/deletion-from-bst/

Code: Alles auswählen

# A class to store a BST node
class Node:
	def __init__(self, data, left=None, right=None):
		self.data = data
		self.left = left
		self.right = right


# Function to perform inorder traversal on the BST
def inorder(root):
	if root is None:
		return

	inorder(root.left)
	print(root.data, end=' ')
	inorder(root.right)


# Helper function to find minimum value node in the subtree rooted at `curr`
def getMinimumKey(curr):
	while curr.left:
		curr = curr.left
	return curr


# Recursive function to insert a key into a BST
def insert(root, key):

	# if the root is None, create a new node and return it
	if root is None:
		return Node(key)

	# if the given key is less than the root node, recur for the left subtree
	if key < root.data:
		root.left = insert(root.left, key)

	# if the given key is more than the root node, recur for the right subtree
	else:
		root.right = insert(root.right, key)

	return root


# Function to delete a node from a BST
def deleteNode(root, key):

	# pointer to store the parent of the current node
	parent = None

	# start with the root node
	curr = root

	# search key in the BST and set its parent pointer
	while curr and curr.data != key:

		# update the parent to the current node
		parent = curr

		# if the given key is less than the current node, go to the left subtree;
		# otherwise, go to the right subtree
		if key < curr.data:
			curr = curr.left
		else:
			curr = curr.right

	# return if the key is not found in the tree
	if curr is None:
		return root

	# Case 1: node to be deleted has no children, i.e., it is a leaf node
	if curr.left is None and curr.right is None:

		# if the node to be deleted is not a root node, then set its
		# parent left/right child to None
		if curr != root:
			if parent.left == curr:
				parent.left = None
			else:
				parent.right = None

		# if the tree has only a root node, set it to None
		else:
			root = None

	# Case 2: node to be deleted has two children
	elif curr.left and curr.right:

		# find its inorder successor node
		successor = getMinimumKey(curr.right)

		# store successor value
		val = successor.data

		# recursively delete the successor. Note that the successor
		# will have at most one child (right child)
		deleteNode(root, successor.data)

		# copy value of the successor to the current node
		curr.data = val

	# Case 3: node to be deleted has only one child
	else:

		# choose a child node
		if curr.left:
			child = curr.left
		else:
			child = curr.right

		# if the node to be deleted is not a root node, set its parent
		# to its child
		if curr != root:
			if curr == parent.left:
				parent.left = child
			else:
				parent.right = child

		# if the node to be deleted is a root node, then set the root to the child
		else:
			root = child

	return root



keys = [50, 70, 90, 63]

root = None
for key in keys:
	root = insert(root, key)

root = deleteNode(root, 70)
root = insert(root, 91)
inorder(root)

Nun würde ich gerne diesen Baum visualisieren auf der Konsole, also so ähnlich wie:

50
/ \
/ \
43 70
/ \
/ \
63 90
\
100

Habt ihr da eine Idee, ob es da was Fertiges gibt?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich denke nicht, dass es da etwas fertiges gibt, insbesondere, wenn man da einfach irgendeine Implementierung aus dem Netz zugrundelegt.

Die einfachste Art, sowas darzustellen, ist graphviz. Ob das auch ein ascii-Backend hat, weiss ich aber nicht aus dem Kopf.
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

duffy6 hat geschrieben: Donnerstag 7. April 2022, 16:20 ich habe mir diesen Binärbaum hier mal angesehen und damit rumgespielt:

https://www.techiedelight.com/deletion-from-bst/
[...]
Nun würde ich gerne diesen Baum visualisieren auf der Konsole, also so ähnlich wie:

50
/ \
/ \
43 70
/ \
/ \
63 90
\
100

Habt ihr da eine Idee, ob es da was Fertiges gibt?
Für Deinen Anwendungsfall gibt es ein fertiges Modul namens binarytree [1] und -- je nachdem, was Du am Ende alles damit machen möchtest -- das darauf aufbauende Modul pybush [2]. HTH, viel Erfolg!

[1] https://pypi.org/project/binarytree/
[2] https://pypi.org/project/pybush/
tonikae
User
Beiträge: 90
Registriert: Sonntag 23. Februar 2020, 10:27

Binärbäume sind eigentlich typisch im Bereich Machine Learning und laufen dort als "DecisionTree".
Das ist der einfachste und am weitesten verbreitete ML-Algorithmus und wird üblicherweise zur Klassizierung
von Daten verwendet.
https://de.wikipedia.org/wiki/Entscheidungsbaum

Bei mir mir wird so ein "DecisionTree" auf der Konsole (nicht in Python ) beispielhaft so dargestellt:

Code: Alles auswählen

Feature 4, Threshold 0.8
L-> Iris-setosa : 35/35
R-> Feature 3, Threshold 4.95
    L-> Feature 4, Threshold 1.7000000000000002
        L-> Iris-versicolor : 25/25
        R-> Iris-virginica : 1/1
    R-> Feature 4, Threshold 1.7000000000000002
        L-> Iris-virginica : 4/5
        R-> Iris-virginica : 28/28
Gezeigt wird hier das bekannte "Iris-Dataset" mit einer Ebenentiefe von 3
"L" und" R" entsprechen eben dem True und False, die Zahlen hinter den
Labels die Anzahl der klassifizierten Datensätze.

Kurz:
Einfach mal gucken, was dir Python in punkto ML/DecisionTree und Textanzeige so anbietet.
Da sollte es schon etwas geben.
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

tonikae hat geschrieben: Freitag 8. April 2022, 09:06 Binärbäume sind eigentlich typisch im Bereich Machine Learning und laufen dort als "DecisionTree".
Das ist der einfachste und am weitesten verbreitete ML-Algorithmus und wird üblicherweise zur Klassizierung
von Daten verwendet.
https://de.wikipedia.org/wiki/Entscheidungsbaum
Das ist natürlich richtig, aber nur ein Anwendungsfall von Binärbäumen.
tonikae hat geschrieben: Freitag 8. April 2022, 09:06 Bei mir mir wird so ein "DecisionTree" auf der Konsole (nicht in Python ) beispielhaft so dargestellt:

Code: Alles auswählen

Feature 4, Threshold 0.8
L-> Iris-setosa : 35/35
R-> Feature 3, Threshold 4.95
    L-> Feature 4, Threshold 1.7000000000000002
        L-> Iris-versicolor : 25/25
        R-> Iris-virginica : 1/1
    R-> Feature 4, Threshold 1.7000000000000002
        L-> Iris-virginica : 4/5
        R-> Iris-virginica : 28/28
Es wäre net gewesen, wenn Du die Library / Software verlinkt hättest, mit der Du Deinen Decision Tree baust und ausgibst. Für scikit-learn wäre das etwa [1], aber das macht eine etwas andere Ausgabe.

[1] https://scikit-learn.org/stable/modules/tree.html
tonikae
User
Beiträge: 90
Registriert: Sonntag 23. Februar 2020, 10:27

LukeNukem hat geschrieben: Freitag 8. April 2022, 10:08 Es wäre net gewesen, wenn Du die Library / Software verlinkt hättest, mit der Du Deinen Decision Tree baust und ausgibst. Für scikit-learn wäre das etwa [1], aber das macht eine etwas andere Ausgabe.
Wie gesagt...es ist kein" Python", sondern "Julia" und das Package heisst in diesem Fall schlicht und einfach "DecisionTree".
Im Normalfall verwende ich für ML-Anwendungen aber eher die Packages "Flux" und "MLJ", weil ich ML generell eher in
"Julia" mache.Weiter will ich das jetzt hier aber nicht ausführen.
btw.
Das Programm ist auch nicht besonders groß( weil es ja nur ein kleiner Test war/ist).
Anguckbar hier:
https://drive.google.com/file/d/1h_mjBx ... tjXU8/view
duffy6
User
Beiträge: 3
Registriert: Donnerstag 7. April 2022, 16:10

Danke Leute für den Tipp mit Pybush!

Ich hab das nun so gelöst - vorsicht, ich bin absoluter Newbie :-)

Code: Alles auswählen

# from binarytree import tree
from pybush import  delete, add, Node

eingabe = int(input("Ersten Wert eingeben: "))
tree_root = Node(eingabe)
while True:
    eingabe2 = input("Add Value (i5) or remove value (r3) or exit(e): ")
    aktion = eingabe2[:1]
    wert = int(eingabe2[1:])
    print(aktion, wert)
    if aktion == "i":
        add(tree_root, wert)
    if aktion == "r":
        delete(tree_root, wert)
    print(tree_root)
    if aktion == "e":
        break


Antworten