A recurring question when working with dependency DAGs is what to call this quantity:
|
|
A node with nothing below it is 0; every other node is one more than the deepest thing it depends on. Is that height or depth? The short answer: by the standard tree analogy it is height, but the word is convention-dependent and the only safe practice is to define the recurrence explicitly rather than rely on the label. This page explains why the ambiguity exists and how to reason about it precisely.
Trees: the Baseline#
The terms come from rooted trees, where they are unambiguous and opposite in direction:
- Depth of a node is the number of edges from the root down to it. The root has depth
0. Depth grows as you move away from the root. - Height of a node is the number of edges on the longest path from it down to a leaf. Leaves have height
0. Height grows as you move toward the root.
The two are measured from opposite ends. Depth counts down from the root; height counts up from the leaves.
Mapping the Recurrence onto the Tree Picture#
The recurrence above bottoms out at nodes with no dependencies and assigns them 0. Those nodes are the sinks of the “depends-on” relation — the analogue of a tree’s leaves. The value then increases as you move toward the nodes that depend on everything else.
That is exactly the tree definition of height: leaves are 0, and a node is 1 + max over its children. So the quantity you asked about is height — specifically, the length of the longest path from the node to a dependency-free sink.
The dual quantity — 0 at the sources (nodes nothing depends on) and 1 + max over predecessors — is depth: the length of the longest path from a source down to the node.
| Recurrence bottoms out at | Counts toward | Equals | |
|---|---|---|---|
| Height(v) | sinks (no dependencies) | sources | longest path from v to a sink |
| Depth(v) | sources (nothing depends on it) | sinks | longest path to v from a source |
Your recurrence is the Height(v) row.
Direction Is the Real Source of Confusion#
A DAG has no single root, so “up” and “down” are not intrinsic — they depend entirely on which way you orient the edges and which end you call the bottom. This is why people disagree:
- Draw dependencies below their dependents (the common “the foundation is at the bottom” mental model) and the leaf-level dependency-free nodes sit at the bottom. Counting up from them is naturally “height.”
- Draw dependents below (a “drill-down into what this needs” mental model) and the same nodes sit at the bottom of a different picture, and many practitioners call your recurrence the dependency depth — “how deep does this thing’s dependency tree go.”
Both camps are internally consistent. Graph-theory-by-tree-analogy says height (leaves = 0). Everyday “how deep is the dependency tree” usage says depth. Neither is wrong; they have just fixed different ends as the origin.
Recommendation: in code and docs, do not lean on the bare word. Either spell it out — longestPathToLeaf, dependencyDepth, topoLevel — or state the recurrence next to the name. If you want a single defensible convention, use height with “sinks are 0,” because it matches the rooted-tree definition every data-structures text already agrees on.
The Pair Does Not Sum to a Constant#
It is tempting to assume depth(v) + height(v) is the same for every node (the total DAG “length”). It is not. For a node v:
|
|
That equals the DAG’s overall critical-path length only if v lies on a longest path. Off the critical path the sum is strictly smaller — the difference is the scheduling slack of that node. This is precisely the ASAP/ALAP reasoning used in PERT/CPM project scheduling.
Pseudocode#
A memoised depth-first traversal computes height in O(V + E):
|
|
This terminates only because the graph is acyclic. If deps ever forms a cycle, the recursion revisits a node already on the call stack — the standard way to detect that the “DAG” is not actually acyclic. A robust implementation tracks an in-progress set and raises on a back edge:
|
|
Related Terms You Will Encounter#
The same quantity travels under several names depending on the field:
- Level or rank — graph drawing (Sugiyama layered layout) calls longest-path layering the node’s level.
- Topological generation — the set of all nodes sharing a given height; generation 0 is exactly the sinks.
- Longest-path layering — the layout algorithm that assigns each node its height (or depth, depending on orientation).
- ASAP / ALAP — “as soon/late as possible” schedules are depth and
criticalPath − heightrespectively.
They are all the same recurrence; only the orientation and the application’s vocabulary differ.
External Links#
- Wikipedia: Tree (data structure) — terminology — the root/leaf, depth/height definitions
- Wikipedia: Longest path problem (acyclic graphs)
- Wikipedia: Critical path method — where height/depth slack is used in practice
- Layered graph drawing — longest-path layering