Day 23 - More trees
Skills: None
Pre-reading: 7.1.3, 7.1.4
Intro (20 mins)
- Yesterday we saw binary trees where each node has exactly two children. Today we explore n-ary trees where nodes can have any number of children.
- Real-world example: an organization chart, where each employee has a name, title, and a (possibly empty) list of direct reports.
- Tables struggle to represent nested relationships naturally—it's hard to find all indirect reports or the depth of the organization.
- Data Definition:
import lists as L
data OrgTree:
| node(name :: String, title :: String, reports :: List<OrgTree>)
end
# Example: A small organization
alex-tree = node("Alex", "Engineer", [list: ])
casey-tree = node("Casey", "Engineer", [list: ])
jordan-tree = node("Jordan", "CTO", [list: alex-tree, casey-tree])
riley-tree = node("Riley", "Accountant", [list: ])
taylor-tree = node("Taylor", "CFO", [list: riley-tree])
avery-tree = node("Avery", "CEO", [list: jordan-tree, taylor-tree]) - Example: Check if someone is a leaf (has no reports):
fun is-leaf(t :: OrgTree) -> Boolean:
cases (OrgTree) t:
| node(name, title, reports) => L.empty(reports)
end
where:
is-leaf(alex-tree) is true
is-leaf(avery-tree) is false
end - Unlike binary trees, n-ary trees usually require mutually recursive functions—one function processes a single tree, another processes a list of trees -- the latter is what is called on the children, and calls back to the former.
- Example: Count all employees in the organization:
fun count-employees(t :: OrgTree) -> Number:
cases (OrgTree) t:
| node(name, title, reports) => 1 + count-employees-list(reports)
end
end
fun count-employees-list(ts :: List<OrgTree>) -> Number:
cases (List) ts:
| empty => 0
| link(first, rest) => count-employees(first) + count-employees-list(rest)
end
where:
count-employees(alex-tree) is 1
count-employees(avery-tree) is 6
end
Class Exercises (35 mins)
- Design a function
all-titles
that returns a list of all titles in the organization tree (duplicates are okay). You'll need bothall-titles
andall-titles-list
functions. - Design a function
count-by-title
that takes anOrgTree
and a title string, and returns the number of employees with that title. - Design a function
find-employee
that takes anOrgTree
and a name, and returns theOrgTree
node for that employee (or a special value if not found). - Design a function
org-height
that returns the number of levels in the organization tree (root is level 1). - Design a function
promote-all
that takes anOrgTree
and a function fromString -> String
, and returns a new tree where every title has been updated by the function. - Design a function
flatten-names
that returns a list of all employee names in the organization (pre-order traversal). - Design a function
count-reports
that takes anOrgTree
and a name, and returns how many people report directly to that employee.
Wrap-up (5 mins)
- N-ary trees represent hierarchical data where nodes can have any number of children.
- Processing n-ary trees requires mutually recursive functions—one for single trees, one for lists of trees.
- The same patterns (counting, transforming, searching) apply to n-ary trees as binary trees.