Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice For each node, check each edge to see if we should add to Breadth-fjrst traversal, core idea: We visit each node once. 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to 5
Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice For each node, check each edge to see if we should add to Breadth-fjrst traversal, core idea: We visit each node once. 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to 5
Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice For each node, check each edge to see if we should add to Breadth-fjrst traversal, core idea: We visit each node once. 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to 5
Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice For each node, check each edge to see if we should add to Breadth-fjrst traversal, core idea: 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to 5 ◮ We visit each node once.
Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice 5 Breadth-fjrst traversal, core idea: 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to ◮ We visit each node once. ◮ For each node, check each edge to see if we should add to
Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, 5 Breadth-fjrst traversal, core idea: 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to ◮ We visit each node once. ◮ For each node, check each edge to see if we should add to ◮ So we check each edge at most twice
Breadth-fjrst search (BFS) Breadth-fjrst traversal, core idea: 1. Use something (e.g. a queue) to keep track of every vertex to visit 2. Add and remove nodes from queue until it’s empty 3. Use a set to store nodes we don’t want to recheck/revisit 4. Runtime: queue 5 ◮ We visit each node once. ◮ For each node, check each edge to see if we should add to ◮ So we check each edge at most twice So, O ( | V | + 2 | E | ) , which simplifjes to O ( | V | + | E | ) .
Breadth-fjrst search (BFS) Pseudocode: 6 search(v): visited = empty set queue.enqueue(v) visited.add(v) while (queue is not empty): curr = queue.dequeue() for (w : v.neighbors()): if (w not in visited): queue.enqueue(w) visited.add(curr)
An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 7
An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 7
An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 7
An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 7
An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 7
An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 7
An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 8
An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 8
An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 8
An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 8
An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 8
search(v): search(v): visited = empty set visited = empty set stack.push(v) queue.enqueue(v) visited.add(v) visited.add(v) while (stack is not empty): while (queue is not empty): curr = stack.pop() curr = queue.dequeue() visited.add(curr) for (w : v.neighbors()): for (w : v.neighbors()): if (w not in visited): if (w not in visited): queue.enqueue(w) stack.push(w) visited.add(curr) visited.add(v) Depth-fjrst search (DFS) The DFS algorithm: Question: Why a queue? Can we use other data structures? The BFS algorithm: and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends 9
search(v): search(v): visited = empty set visited = empty set stack.push(v) queue.enqueue(v) visited.add(v) visited.add(v) while (stack is not empty): while (queue is not empty): curr = stack.pop() curr = queue.dequeue() visited.add(curr) for (w : v.neighbors()): for (w : v.neighbors()): if (w not in visited): if (w not in visited): queue.enqueue(w) stack.push(w) visited.add(curr) visited.add(v) Depth-fjrst search (DFS) The DFS algorithm: Question: Why a queue? Can we use other data structures? The BFS algorithm: and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends 9
search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(v) Depth-fjrst search (DFS) The DFS algorithm: 9 The BFS algorithm: Question: Why a queue? Can we use other data structures? and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends search(v): visited = empty set queue.enqueue(v) visited.add(v) while (queue is not empty): curr = queue.dequeue() for (w : v.neighbors()): if (w not in visited): queue.enqueue(w) visited.add(curr)
Depth-fjrst search (DFS) Question: Why a queue? Can we use other data structures? The DFS algorithm: 9 The BFS algorithm: and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends search(v): search(v): visited = empty set visited = empty set stack.push(v) queue.enqueue(v) visited.add(v) visited.add(v) while (stack is not empty): while (queue is not empty): curr = stack.pop() curr = queue.dequeue() visited.add(curr) for (w : v.neighbors()): for (w : v.neighbors()): if (w not in visited): if (w not in visited): queue.enqueue(w) stack.push(w) visited.add(curr) visited.add(v)
Depth-fjrst search (DFS) example e Visited: a, Stack: a, Current node: j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, Stack: Current node: a j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, Stack: b, d, Current node: a j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, Stack: b, Current node: d j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, Stack: b, e, f, g, Current node: d j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, Stack: b, e, f, Current node: g j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, Stack: b, e, f, h, i, Current node: g j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, Stack: b, e, f, h, Current node: i j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, Stack: b, e, f, Current node: h j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, Stack: b, e, Current node: f j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, Stack: b, e, Current node: e j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: b, e, c, Current node: e j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: b, Current node: c j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: Current node: b j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: Current node: j c i h g f d b a 10 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)
search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(curr) Depth-fjrst search (DFS) Depth-fjrst traversal, core idea: Pseudocode: for same reasons as BFS E V 2. Runtime: also everything the same. 1. Instead of using a queue, use a stack. Otherwise, keep 11
search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(curr) Depth-fjrst search (DFS) Depth-fjrst traversal, core idea: Pseudocode: everything the same. 1. Instead of using a queue, use a stack. Otherwise, keep 11 2. Runtime: also O ( | V | + | E | ) for same reasons as BFS
Depth-fjrst search (DFS) Pseudocode: Depth-fjrst traversal, core idea: 11 everything the same. 1. Instead of using a queue, use a stack. Otherwise, keep 2. Runtime: also O ( | V | + | E | ) for same reasons as BFS search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(curr)
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 12
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 13
Compare and contrast Question: When do we use BFS vs DFS? Related question: How much memory does BFS and DFS use in the worst case? BFS: V – what if every node is connected to the start? DFS: V – what if the nodes are arranged like a linked list? So, in the worst case, BFS and DFS both have the same worst-case runtime and memory usage. They only difger in what order they visit the nodes. 14
Compare and contrast Question: When do we use BFS vs DFS? Related question: How much memory does BFS and DFS use in the worst case? V – what if every node is connected to the start? V – what if the nodes are arranged like a linked list? So, in the worst case, BFS and DFS both have the same worst-case runtime and memory usage. They only difger in what order they visit the nodes. 14 ◮ BFS: ◮ DFS:
Compare and contrast Question: When do we use BFS vs DFS? Related question: How much memory does BFS and DFS use in the worst case? list? So, in the worst case, BFS and DFS both have the same worst-case runtime and memory usage. They only difger in what order they visit the nodes. 14 ◮ BFS: O ( | V | ) – what if every node is connected to the start? ◮ DFS: O ( | V | ) – what if the nodes are arranged like a linked
Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? BFS: “width” of tree num leaves DFS: height For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 15
Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? BFS: “width” of tree num leaves DFS: height For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 15
Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? “width” of tree num leaves height For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 15 ◮ BFS: ◮ DFS:
Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 15 ◮ BFS: O ( “width” of tree ) = O ( num leaves ) ◮ DFS: O ( height )
Recommend
More recommend