A search state alone cannot tell you how you reached it. A `Node<T>` wraps the state with a parent link, a cost, and a heuristic. The initial node has no parent; nodes created during a search can point back toward it. section 2.2
class Node<T>: Comparable, Hashable {
let state: T
let parent: Node?
let cost: Float
let heuristic: Float
init(state: T, parent: Node?, cost: Float = 0.0, heuristic: Float = 0.0) {
self.state = state
self.parent = parent
self.cost = cost
self.heuristic = heuristic
}
var hashValue: Int { return Int(cost + heuristic) }
}
func < <T>(lhs: Node<T>, rhs: Node<T>) -> Bool {
return (lhs.cost + lhs.heuristic) < (rhs.cost + rhs.heuristic)
}
func == <T>(lhs: Node<T>, rhs: Node<T>) -> Bool {
return lhs === rhs
}
The Swift definition compares nodes by cost plus heuristic, but tests equality by identity. section 2.2
Depth-first and breadth-first search keep nodes in their frontiers while tracking explored states separately. Once either search reaches the goal, `nodeToPath` follows parent links backward to recover the route. A* also uses each node’s cost and heuristic to prioritize its frontier. section 2.2
