Trees and Tree Traversal Definition of a Tree
Total Page:16
File Type:pdf, Size:1020Kb
Trees and Tree Traversal Material adapted – courtesy of Prof. Dave Matuszek at UPENN Definition of a tree A tree is a node with a value and zero or more children Depending on the needs of the program, the children may or may not be ordered A tree has a root, internal nodes, and leaves A Each node contains an element and has branches B C D E leading to other nodes (its children) F G H I J K Each node (other than the root) has a parent L M N Each node has a depth (distance from the root) 2 1 More definitions An empty tree has no nodes The descendents of a node are its children and the descendents of its children The ancestors of a node are its parent (if any) and the ancestors of its parent The subtree rooted at a node consists of the given node and all its descendents An ordered tree is one in which the order of the children is important; an unordered tree is one in which the children of a node can be thought of as a set The branching factor of a node is the number of children it has The branching factor of a tree is the average branching factor of its nodes 3 File systems File systems are almost always implemented as a tree structure The nodes in the tree are of (at least) two types: folders (or directories), and plain files A folder typically has children—subfolders and plain files A plain file is typically a leaf 4 2 Family trees It turns out that a tree is not a good way to represent a family tree Every child has two parents, a mother and a father Parents frequently remarry An “upside down” binary tree almost works Since it is a biological fact (so far) that every child has exactly two parents, we can use left child = father and right child = mother The terminology gets a bit confusing If you could go back far enough, it becomes a mathematical certainty that the mother and father have some ancestors in common 5 Part of a genealogy Chester Elaine Eugene Pauline David Paula Winfred Carol Steven Danielle Isaac 6 3 Game trees Trees are used heavily in implementing games, particularly board games A node represents a position on the board The children of a node represent all the possible moves from that position More precisely, the branches from a node represent the possible moves; the children represent the new positions Planning ahead (in a game) means choosing a path through the tree However— You can’t have a cycle in a tree If you can return to a previous position in a game, you have a cycle Graphs can have cycles 7 Tree searches A tree search starts at the root A and explores nodes from there, looking for a goal node (a node that satisfies certain B C conditions, depending on the problem) D E F G For some problems, any goal node is acceptable (N or J); H I J K for other problems, you want a minimum-depth goal node, that is, a goal node nearest the L M N O P Q root (only J) Goal nodes 8 4 Depth-first searching A depth-first search (DFS) A explores a path all the way to a leaf before backtracking and exploring another path B C For example, after searching A, then B, then D, the search D E F G backtracks and tries another path from B H I J K Node are explored in the order A B D E H L M N I O P C F G J K Q L M N O P Q N will be found before J 9 How to do depth-first searching Put the root node on a stack; while (stack is not empty) { remove a node from the stack; if (node is a goal node) return success; put all children of node onto the stack; } return failure; At each step, the stack contains some nodes from each of a number of levels The size of stack that is required depends on the branching factor b While searching level n, the stack contains approximately b*n nodes 10 5 Recursive depth-first search Recursion is always implemented with a stack. Anything you can do with recursion, you can do with stacks, and vice-versa search(node): print node and if node is a goal, return success; for each child c of node { print c and if search(c) is successful, return success; } return failure; 11 Recursive depth-first search search(node): print node and if node is a goal, return success; for each child c of node { print c and if search(c) is successful, return success; } return failure; The (implicit) stack contains only the nodes on a path from the root to a goal When a solution is found, the path is on the (implicit) stack, and can be extracted as the recursion “unwinds” You can do this by (for example) substituting pushing values onto a stack for the above print statements 12 6 Breadth-first searching A breadth-first search (BFS) A explores nodes nearest the root before exploring nodes further away B C For example, after searching A, then B, then C, the search D E F G proceeds with D, E, F, G Node are explored in the order H I J K A B C D E F G H I J K L M N O P Q J will be found before N L M N O P Q 13 How to do breadth-first searching Put the root node on a queue; while (queue is not empty) { remove a node from the queue; if (node is a goal node) return success; put all children of node onto the queue; } return failure; 14 7 Comparison of algorithms Depth-first searching: Put the root node on a stack; while (stack is not empty) { remove a node from the stack; if (node is a goal node) return success; put all children of node onto the stack; } return failure; Breadth-first searching: Put the root node on a queue; while (queue is not empty) { remove a node from the queue; if (node is a goal node) return success; put all children of node onto the queue; } return failure; 15 How to do breadth-first searching Put the root node on a queue; while (queue is not empty) { remove a node from the queue; if (node is a goal node) return success; put all children of node onto the queue; } return failure; Just before starting to explore level n, the queue holds all the nodes at level n-1 In a typical tree, the number of nodes at each level increases exponentially with the depth Memory requirements may be infeasible When this method succeeds, it doesn’t give the path There is no “recursive” breadth-first search equivalent to recursive depth-first search 16 8 Depth- vs. breadth-first searching When a breadth-first search succeeds, it finds a minimum-depth (nearest the root) goal node When a depth-first search succeeds, the found goal node is not necessarily minimum depth For a large tree, breadth-first search memory requirements may be excessive For a large tree, a depth-first search may take a very long time to find even a very nearby goal node There is a way to combine the two, but it is beyond the scope of this class. Channel your inner Googler to look up Depth-limited searching and iterative deepening. 17 Thank you! 18 9.