class Node:
def __init__(self, val):
self.val = val
self.children = []
class Tree:
def __init__(self, root):
self.root = root
def add_child(self, parent, child):
# Trees allow only one parent per node
parent.children.append(child)
class Graph:
def __init__(self):
self.adj = {}
def add_node(self, val):
if val not in self.adj:
self.adj[val] = []
def add_edge(self, src, dest):
# Graphs allow cycles and multiple edges
self.adj[src].append(dest)
# Build tree
A = Node('A')
B = Node('B')
C = Node('C')
tree = Tree(A)
tree.add_child(A, B)
tree.add_child(A, C)
# Build graph
graph = Graph()
for node in ['A', 'B', 'C', 'D']:
graph.add_node(node)
graph.add_edge('A', 'B')
graph.add_edge('B', 'C')
graph.add_edge('C', 'A') # cycle
graph.add_edge('A', 'D')
# Print tree structure
print('Tree:')
print(f'{tree.root.val}')
print(f'/ \
{tree.root.children[0].val} {tree.root.children[1].val}')
# Print graph adjacency
print('\nGraph:')
for node in graph.adj:
print(f'{node} -> {graph.adj[node]}')parent.children.append(child)
Add child to parent's children list, maintaining tree structure
self.adj[src].append(dest)
Add directed edge from src to dest, allowing cycles
Tree:
A
/ \
B C
Graph:
A -> ['B', 'D']
B -> ['C']
C -> ['A']
D -> []