Step 1 of 6
Binary trees and recursion
Lists and arrays are linear: each element has one next element. A tree branches: each node can have several children, and every node except the top one (the root) has exactly one parent. File systems, HTML pages, company org charts and the std::map you've been using are all trees.
In a binary tree, each node has at most two children, called left and right. Ownership is naturally a tree too, so std::unique_ptr children mean the whole tree frees itself when the root goes away:
struct Node {
int value;
std::unique_ptr<Node> left, right;
};
Thinking recursively
A tree is either empty, or a node whose left and right children are smaller trees. So almost every tree algorithm has the same shape:
- Handle the empty tree (
nullptr). This is the base case. - Ask the same question of the left and right subtrees.
- Combine their answers with the current node.
#include <algorithm>
#include <iostream>
#include <memory>
struct Node {
int value;
std::unique_ptr<Node> left, right;
};
std::unique_ptr<Node> leaf(int v) { return std::make_unique<Node>(Node{v, nullptr, nullptr}); }
int count(const Node* n) {
if (!n) return 0; // empty tree
return 1 + count(n->left.get()) + count(n->right.get()); // me + both sides
}
int max_value(const Node* n) {
int best = n->value; // assumes n isn't null
if (n->left) best = std::max(best, max_value(n->left.get()));
if (n->right) best = std::max(best, max_value(n->right.get()));
return best;
}
int main() {
/* 4
/ \
9 2
/
7 */
auto root = leaf(4);
root->left = leaf(9);
root->right = leaf(2);
root->right->left = leaf(7);
std::cout << count(root.get()) << " nodes, max " << max_value(root.get()) << "\n";
}
4 nodes, max 9
How it works
count(nullptr)is 0. For a real node, it's 1 (the node itself) plus the counts of both subtrees. Trust the recursion: you don't need to trace every call to know it's right..get()turns aunique_ptrinto a plainconst Node*for reading. Functions that only look at a tree take raw pointers; ownership stays with theunique_ptrs.
Your task
- height: an empty tree has height 0. A node's height is 1 plus the larger of its two subtrees' heights (
std::maxfrom<algorithm>). - sum: like
count, but addn->valueinstead of 1. Returnlongso big trees don't overflow.
Your turn: write height (an empty tree has height 0, a single node 1) and sum.