DFS & BFS
来源:互联网 发布:淘宝达人是怎么赚钱的 编辑:程序博客网 时间:2024/05/16 13:00
DFS (Depth First Search) and BFS (Breadth First Search) are search algorithms used for graphs and trees. When you have an ordered tree or graph, like a BST, it’s quite easy to search the data structure to find the node that you want. But, when given an unordered tree or graph, the BFS and DFS search algorithms can come in handy to find what you’re looking for. The decision to choose one over the other should be based on the type of data that one is dealing with.
In a breadth first search, you start at the root node, and then scan each node in the first level starting from the leftmost node, moving towards the right. Then you continue scanning the second level (starting from the left) and the third level, and so on until you’ve scanned all the nodes, or until you find the actual node that you were searching for. In a BFS, when traversing one level, we need some way of knowing which nodes to traverse once we get to the next level. The way this is done is by storing the pointers to a level’s child nodes while searching that level. The pointers are stored in FIFO (First-In-First-Out) queue. This, in turn, means that BFS uses a large amount of memory because we have to store the pointers.
Subscribe to our newsletter for more free interview questions.
An example of BFS
Here’s an example of what a BFS would look like. The numbers represent the order in which the nodes are accessed in a BFS:
In a depth first search, you start at the root, and follow one of the branches of the tree as far as possible until either the node you are looking for is found or you hit a leaf node ( a node with no children). If you hit a leaf node, then you continue the search at the nearest ancestor with unexplored children.
An example of DFS
Here’s an example of what a DFS would look like. The numbers represent the order in which the nodes are accessed in a DFS:
Differences between DFS and BFS
Comparing BFS and DFS, the big advantage of DFS is that it has much lower memory requirements than BFS, because it’s not necessary to store all of the child pointers at each level. Depending on the data and what you are looking for, either DFS or BFS could be advantageous.
For example, given a family tree if one were looking for someone on the tree who’s still alive, then it would be safe to assume that person would be on the bottom of the tree. This means that a BFS would take a very long time to reach that last level. A DFS, however, would find the goal faster. But, if one were looking for a family member who died a very long time ago, then that person would be closer to the top of the tree. Then, a BFS would usually be faster than a DFS. So, the advantages of either vary depending on the data and what you’re looking for.
DFS 深度优先
假设右边的树代表一个公司的组织架构,每个node是一个部门。若要计算部门c的总收入,我们必须先知道e和f的,而要知道e的总收入我们必须先知道g和h,这就是典型的深度优先。深度优先通过递归来实现,代码如下:
visitDFS(a); // visit from the root
// performs DFS from the given node
public void visitDFS(Node nodeStart) {
// (1) Entering node - pre-order walk
for(Node child : nodeStart.children) {
visitDFS(child); // recursive call
}
// (2) Leaving node - post-order walk
System.out.println("DFS: " + nodeStart.nodeName);
}
在代码中,我做了两个标记(1)和(2). 在(1)处,当前节点的所有下属节点尚未被访问,而在(2)处,其所有下属节点均被处理完毕。若要计算部门收入,很明显是在(2)处。上面代码打印结果是:d b g h e f c a
BFS 广度优先
假设我们要打印各部门收入报表给CEO,因为每个部门收入数据较多,CEO倾向先看各大部门(只有对某部门数据有疑惑时,才看小部门), 这样情况下是先打印大部门,再打印小部门,低等级部门后打印,这就是广度优先的情况。graph的BFS算法较繁琐,但tree的BFS就非常简单了:
visitBFS(a); // visit from the root
// performs BFS from the given node
public void visitBFS(Node nodeStart) {
List<NODE> pendingExplore = new ArrayList<NODE>(); // list of nodes pending exploration
pendingExplore.add(nodeStart);
while(pendingExplore.size() > 0) {
Node currentNode = pendingExplore.remove(0);
System.out.println("BFS: " + currentNode.nodeName);
pendingExplore.addAll(currentNode.children); // (3)
}
}
上面代码打印结果: a b c d e f g h. 有时同级部门之间还有顺序,譬如重要产品部门比技术支持部门往往排序靠前,要实现这个非常简单,在(3)处,将子节点添加到pendingExplore之前进行sort即可。
附:测试程序的完整代码:
public class TestTree {
public Node a;
@SuppressWarnings("unused")
public TestTree() {
// Construct the tree.
a = new Node("a");
Node b = a.createChildNode("b");
Node c = a.createChildNode("c");
Node d = b.createChildNode("d");
Node e = c.createChildNode("e");
Node f = c.createChildNode("f");
Node g = e.createChildNode("g");
Node h = e.createChildNode("h");
}
public void testDFS() {
System.out.println("Testing DFS");
visitDFS(a); // visit from the root
}
// performs DFS from the given node
public void visitDFS(Node nodeStart) {
// Entering node - pre-order walk
for (Node child : nodeStart.children) {
visitDFS(child); // recursive call
}
// Leaving node - post-order walk
System.out.println("DFS: " + nodeStart.nodeName);
}
public void testBFS() {
System.out.println("Testing BFS");
visitBFS(a); // visit from the root
}
// performs BFS from the given node
public void visitBFS(Node nodeStart) {
List<Node> pendingExplore = new ArrayList<Node>(); // list of nodes
// pending
// exploration
pendingExplore.add(nodeStart);
while (pendingExplore.size() > 0) {
Node currentNode = pendingExplore.remove(0);
System.out.println("BFS: " + currentNode.nodeName);
pendingExplore.addAll(currentNode.children);
}
}
// Application entry point
public static void main(String[] args) {
TestTree testTree = new TestTree();
testTree.testBFS();
testTree.testDFS();
}
// Node class
public static class Node {
public Node parent;
public List<Node> children = new ArrayList<Node>();
public String nodeName;
public Node(String nodeName) {
this.nodeName = nodeName;
}
public Node createChildNode(String childNodeName) {
Node child = new Node(childNodeName);
child.parent = this;
children.add(child);
return child;
}
}
}
- BFS-DFS
- BFS DFS
- DFS+BFS
- BFS DFS
- DFS BFS
- DFS & BFS
- BFS,DFS
- dfs bfs
- BFS&DFS
- DFS BFS
- BFS && DFS
- BFS DFS
- DFS & BFS
- DFS&BFS
- BFS&DFS
- dfs && bfs
- dfs bfs
- BFS/DFS
- caffe_cpp_api
- Android Studio实践运用中遇到问题总结
- 老程序员给初学者的一些建议和忠告
- JavaScript学习手记1
- codeforces 349B Color the Fence
- DFS & BFS
- 用gdb来调试对stl的空vector进行操作而产生的core
- Android activity的生命周期
- Android Volley源码分析(二) 核心功能解析
- 代码自写枚举(多枚举变量同时使用)
- Mac平台搭建php平台
- 1115笔记
- 自用图片
- VIM的一些自己的使用tips(5年前整理的,看到后热泪盈眶)