广度优先搜索和深度优先搜索

时间:2010-03-24 04:58:31

标签: algorithm search

任何人都可以提供一个关于BFS和DFS的简单解释的链接吗?

11 个答案:

答案 0 :(得分:35)

深度优先搜索:

alt text

答案 1 :(得分:26)

假设您有以下结构:

Format: Node [Children]

A [B C D]
B [E F]
C [G]
D []
E []
F []
G []

广度优先搜索会在访问孩子之前访问所有节点的孩子。这是上述结构的伪代码和解决方案:

1. Enqueue root node.
2. Dequeue and output. If the queue is empty, go to step 5.
3. Enqueue the dequeued node's children.
4. Go to Step 2.
5. Done
Two queues: (Active Node) [Output] [Working Set]
Starting with root:
( ) []              [A]
(A) [A]             [B C D] 
(B) [A B]           [C D E F] 
(C) [A B C]         [D E F G] 
(D) [A B C D]       [E F G] 
(E) [A B C D E]     [F G] 
(F) [A B C D E F]   [G] 
(G) [A B C D E F G] [] 

Done

深度优先搜索首先访问树的最低级别(最深的子级)。深度优先搜索有两种类型:预订和后订购。这只是区分何时将节点添加到输出中(当您访问它时与保留它)。

    var rootNode = structure.getRoot();
    var preOrder = new Array();
    var postOrder = new Array();
    function DepthFirst( rootNode ){
        // Pre-order
        preOrder[ preOrder.length ] = rootNode;

        for( var child in rootNode ){
            DepthFirst( child );
        }

        // Post-order
        postOrder[ postOrder.length ] = rootNode;
    }
Pre-order:
* A B E F C G D

Post-order:
* E F B G C D A

答案 2 :(得分:7)

假设你有一棵树如下:

alt text http://i40.tinypic.com/289aslh.jpg

这可能有点令人困惑,因为E既是A和F的孩子,但它有助于说明深度优先搜索的深度。深度优先搜索首先搜索树深(因此称为深度)。因此,从左到右的遍历将是A,B,D,F,E,C,G。

广度优先搜索首先评估所有孩子,然后再继续孩子的孩子。所以同一棵树就会出现A,B,C,E,D,F,G。

希望这有帮助。

答案 3 :(得分:5)

你可以在维基上找到所有内容:

BFSDFS

link也很有用。如果您想要实施,请转到:c++ boost library: DFS

答案 4 :(得分:3)

以下是一些要查看的链接:

  

BFS是一种不知情的搜索方法,旨在通过系统地搜索每个解决方案来扩展和检查图形或序列组合的所有节点。换句话说,它会在没有考虑目标的情况下彻底搜索整个图形或序列,直到找到它为止。

  

正式地,DFS是一种不知情的搜索,它通过展开出现的搜索树的第一个子节点来进行,从而越来越深,直到找到目标节点,或直到它到达没有子节点的节点。然后搜索回溯,返回到最近的节点,它还没有完成探索

它们不仅包含有关如何在应用程序中实现它们的良好解释,还包含一些算法伪代码。

答案 5 :(得分:2)

答案 6 :(得分:1)

使用dfs和bfs进行图遍历。

<{3}}和c++中的

答案 7 :(得分:1)

在基础知识中提到了这个想法:

获取一个新队列...使用根节点初始化....循环遍历整个队列并继续从队列中删除项目并将其打印出来(或保存等)并检查相同的项目是否有任何孩子,如果是这样,将他们推入队列并继续循环,直到你遍历整个片段(图)...

答案 8 :(得分:1)

两个指针的片段。

void BFS(int v,struct Node **p)
{
     struct Node *u;

     visited[v-1] = TRUE;
     printf("%d\t",v);
     AddQueue(v);

     while(IsEmpty() == FALSE)
     {
         v = DeleteQueue();
         u = *(p+v-1);

         while(u!=NULL)
         {
            if(visited(u->data -1) == FALSE)
            {
                  AddQueue(u->data);
                  visited[u->data -1]=TRUE;
                  printf("%d\t",u->data);
            }

            u = u->next;
         }
     }
}

答案 9 :(得分:0)

BFS和DFS适用于各种图表。我只为二叉树解释它。 BFS从上到下,从左到右访问每个节点。例如:

       1
      / \
     7   9
     \  / \
      8 2 3

BFS给我们:1 7 9 8 2 3. DFS首先访问每个分支的深度。然后,它又回到了它的父母那里。您可以遵循这个非正式规则。先左孩子然后右孩子然后父母。但是,你需要从每个分支的深度开始。例如,这里你从8开始,因为没有7的左子。然后,你访问父7。然后,将访问7的1个父亲。然后,你去右边的分支。但是,这次有2个是最左边的孩子。所以,你访问2(左孩子)然后,右孩子3,然后9他们的父母。所以,DFS给了我们8 7 1 2 9 3.这是实施:

import java.util.ArrayList;
import java.util.List;

public class TreeTraverse {

    static class Node{
        Node(int data){
            this.data = data;
            this.left = null;
            this.right = null;
            this.visited = false;
        }
        int data;
        Node left;
        Node right;
        boolean visited;
    }

    public static void main(String[] args) {
        //The tree:
        //   1
        //  / \
        // 7   9
        // \  / \
        //  8 2 3

        Node node1 = new Node(1);
        Node node7 = new Node(7);
        Node node9 = new Node(9);
        Node node8 = new Node(8);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        node1.left = node7;
        node1.right = node9;
        node7.right = node8;
        node9.right = node3;
        node9.left = node2;
        System.out.println("DFS: ");
        depthFirstSearch(node1);
        System.out.println("\nBFS: ");
        breadthFirstSearch(node1);

    }

    private static void depthFirstSearch(Node node){
        if(node.left == null && node.right == null){
            System.out.print(node.data+" ");
            node.visited = true;
        }else if(node.left == null || node.left.visited){
            depthFirstSearch(node.right);
            System.out.print(node.data+" ");
            node.visited = true;
        }else{
            depthFirstSearch(node.left);
            node.visited = true;
            System.out.print(node.data+" ");
            depthFirstSearch(node.right);

        }
    }

    private static void breadthFirstSearch(Node node){
        List<Node> al = new ArrayList<>();
        al.add(node);
        while(!al.isEmpty()){
            node = al.get(0);
            if(node.left != null){
                int index = al.size();
                al.add(index,node.left);
            }
            if(node.right != null){
                int index = al.size();
                al.add(index,node.right);
            }
            System.out.print(al.get(0).data+" ");
            al.remove(0);


        }
    }

}

我希望它有所帮助。如果要克隆项目,请访问:https://github.com/m-vahidalizadeh/foundations/blob/master/src/algorithms/TreeTraverse.java。我希望它有所帮助。

答案 10 :(得分:0)

首先,BFS和DFS是实现二叉树遍历的两种方式。广度优先意味着级别订单遍历。 Depth First有三种实现方式 - ,,。

预购:

a. Start with root,
b. mark it visited,
c. go to left node
d. (b) - mark it visited
e. Repeat (c) till there is not any new left node remaining
 (We are/might be at leaf node at this point,)
f. Is there any right node available? If yes, go to (a).

级别订单遍历 时间复杂性 O(n) - 每个节点被访问的次数仅为1,意味着总数为n次。

空间复杂性 - 最佳案例:树只剩下节点,是O(1) 平均情况:完美二叉树是示例,n / 2个节点数,O(n)