深度优先遍历 订阅
深度优先搜索是一种在开发爬虫早期使用较多的方法。它的目的是要达到被搜索结构的叶结点(即那些不包含任何超链的HTML文件) 。在一个HTML文件中,当一个超链被选择后,被链接的HTML文件将执行深度优先搜索,即在搜索其余的超链结果之前必须先完整地搜索单独的一条链。深度优先搜索沿着HTML文件上的超链走到不能再深入为止,然后返回到某一个HTML文件,再继续选择该HTML文件中的其他超链。当不再有其他超链可选择时,说明搜索已经结束。 [1] 展开全文
深度优先搜索是一种在开发爬虫早期使用较多的方法。它的目的是要达到被搜索结构的叶结点(即那些不包含任何超链的HTML文件) 。在一个HTML文件中,当一个超链被选择后,被链接的HTML文件将执行深度优先搜索,即在搜索其余的超链结果之前必须先完整地搜索单独的一条链。深度优先搜索沿着HTML文件上的超链走到不能再深入为止,然后返回到某一个HTML文件,再继续选择该HTML文件中的其他超链。当不再有其他超链可选择时,说明搜索已经结束。 [1]
信息
提出者
霍普克洛夫特与罗伯特·塔扬
应用学科
计算机
中文名
深度优先搜索
外文名
Depth-First-Search
深度优先搜索详细解释
事实上,深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.举例说明之:下图是一个无向图,如果我们从A点发起深度优先搜索(以下的访问次序并不是唯一的,第二个点既可以是B也可以是C,D),则我们可能得到如下的一个访问过程:A->B->E(没有路了!回溯到A)->C->F->H->G->D(没有路,最终回溯到A,A也没有未访问的相邻节点,本次搜索结束). 简要说明深度优先搜索的特点:每次深度优先搜索的结果必然是图的一个连通分量.深度优先搜索可以从多点发起.如果将每个节点在深度优先搜索过程中的"结束时间"排序(具体做法是创建一个list,然后在每个节点的相邻节点都已被访问的情况下,将该节点加入list结尾,然后逆转整个链表),则我们可以得到所谓的"拓扑排序",即topological sort. [1] 
收起全文
精华内容
下载资源
问答
  • 深度优先遍历和广度优先遍历

    万次阅读 多人点赞 2019-05-29 21:24:38
    深度优先遍历和广度优先遍历 什么是 深度/广度 优先遍历? 深度优先遍历简称DFS(Depth First Search),广度优先遍历简称BFS(Breadth First Search),它们是遍历图当中所有顶点的两种方式。 这两...

    深度优先遍历和广度优先遍历
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    什么是 深度/广度 优先遍历?

    深度优先遍历简称DFS(Depth First Search),广度优先遍历简称BFS(Breadth First Search),它们是遍历图当中所有顶点的两种方式。

    这两种遍历方式有什么不同呢?我们来举个栗子:

    我们来到一个游乐场,游乐场里有11个景点。我们从景点0开始,要玩遍游乐场的所有景点,可以有什么样的游玩次序呢?

    在这里插入图片描述
    第一种是一头扎到底的玩法。我们选择一条支路,尽可能不断地深入,如果遇到死路就往回退,回退过程中如果遇到没探索过的支路,就进入该支路继续深入。

    在图中,我们首先选择景点1的这条路,继续深入到景点7、景点8,终于发现走不动了(景点旁边的数字代表探索次序):
    在这里插入图片描述
    于是,我们退回到景点7,然后探索景点10,又走到了死胡同。于是,退回到景点1,探索景点9:
    在这里插入图片描述
    按照这个思路,我们再退回到景点0,后续依次探索景点2、3、5、4、6,终于玩遍了整个游乐场:
    在这里插入图片描述
    像这样先深入探索,走到头再回退寻找其他出路的遍历方式,就叫做深度优先遍历(DFS)。
    在这里插入图片描述
    在这里插入图片描述
    除了像深度优先遍历这样一头扎到底的玩法以外,我们还有另一种玩法:首先把起点相邻的几个景点玩遍,然后去玩距离起点稍远一些(隔一层)的景点,然后再去玩距离起点更远一些(隔两层)的景点…

    在图中,我们首先探索景点0的相邻景点1、2、3、4:
    在这里插入图片描述
    接着,我们探索与景点0相隔一层的景点7、9、5、6:
    在这里插入图片描述
    最后,我们探索与景点0相隔两层的景点8、10:
    在这里插入图片描述
    像这样一层一层由内而外的遍历方式,就叫做广度优先遍历(BFS)。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    深度优先遍历

    首先说说深度优先遍历的实现过程。这里所说的回溯是什么意思呢?回溯顾名思义,就是自后向前,追溯曾经走过的路径。

    我们把刚才游乐场的例子抽象成数据结构的图,假如我们依次访问了顶点0、1、7、8,发现无路可走了,这时候我们要从顶点8退回到顶点7。

    在这里插入图片描述
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190529211147549.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2EyMjE3MDE4MTAz,size_16,color_FFFFFF,t_70

    而后我们探索了顶点10,又无路可走了,这时候我们要从顶点10退回到顶点7,再退回到顶点1。
    在这里插入图片描述
    像这样的自后向前追溯曾经访问过的路径,就叫做回溯。

    要想实现回溯,可以利用栈的先入后出特性,也可以采用递归的方式(因为递归本身就是基于方法调用栈来实现)。

    下面我们来演示一下具体实现过程。

    首先访问顶点0、1、7、8,这四个顶点依次入栈,此时顶点8是栈顶:
    在这里插入图片描述
    从顶点8退回到顶点7,顶点8出栈:
    在这里插入图片描述
    接下来访问顶点10,顶点10入栈:
    在这里插入图片描述
    从顶点10退到顶点7,从顶点7退到顶点1,顶点10和顶点7出栈:
    在这里插入图片描述
    探索顶点9,顶点9入栈:
    在这里插入图片描述
    以此类推,利用这样一个临时栈来实现回溯,最终遍历完所有顶点。

    广度优先遍历

    接下来该说说广度优先遍历的实现过程了。刚才所说的重放是什么意思呢?似乎听起来和回溯差不多?其实,回溯与重放是完全相反的过程。

    仍然以刚才的图为例,按照广度优先遍历的思想,我们首先遍历顶点0,然后遍历了邻近顶点1、2、3、4:

    在这里插入图片描述
    接下来我们要遍历更外围的顶点,可是如何找到这些更外围的顶点呢?我们需要把刚才遍历过的顶点1、2、3、4按顺序重新回顾一遍,从顶点1发现邻近的顶点7、9;从顶点3发现邻近的顶点5、6。
    在这里插入图片描述
    像这样把遍历过的顶点按照之前的遍历顺序重新回顾,就叫做重放。同样的,要实现重放也需要额外的存储空间,可以利用队列的先入先出特性来实现。

    下面我们来演示一下具体实现过程。
    首先遍历起点顶点0,顶点0入队:
    在这里插入图片描述
    接下来顶点0出队,遍历顶点0的邻近顶点1、2、3、4,并且把它们入队:
    在这里插入图片描述
    然后顶点1出队,遍历顶点1的邻近顶点7、9,并且把它们入队:
    在这里插入图片描述
    然后顶点2出队,没有新的顶点可入队:
    在这里插入图片描述
    以此类推,利用这样一个队列来实现重放,最终遍历完所有顶点。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    /**

    图的顶点
    
    / private static class Vertex { int data; Vertex(int data) {    this.data = data; } } /*
    
    图(邻接表形式)
    
    / private static class Graph { private int size; private Vertex[] vertexes; private LinkedList adj[]; Graph(int size){    this.size = size;    //初始化顶点和邻接矩阵    vertexes = new Vertex[size];    adj = new LinkedList[size];    for(int i=0; i*
    
    深度优先遍历
    
    / public static void dfs(Graph graph, int start, boolean[] visited) { System.out.println(graph.vertexes[start].data); visited[start] = true; for(int index : graph.adj[start]){    if(!visited[index]){        dfs(graph, index, visited);    } } } /*
    
    广度优先遍历
    
    */
    
    public static void bfs(Graph graph, int start, boolean[] visited, LinkedList queue) {
    
    queue.offer(start);
    
    while (!queue.isEmpty()){
    
       int front = queue.poll();
    
       if(visited[front]){
    
           continue;
    
       }
    
       System.out.println(graph.vertexes[front].data);
    
       visited[front] = true;
    
       for(int index : graph.adj[front]){
    
           queue.offer(index);;
    
       }
    
    }
    
    }
    
    public static void main(String[] args) {
    
    Graph graph = new Graph(6);
    
    graph.adj[0].add(1);
    
    graph.adj[0].add(2);
    
    graph.adj[0].add(3);
    
    graph.adj[1].add(0);
    
    graph.adj[1].add(3);
    
    graph.adj[1].add(4);
    
    graph.adj[2].add(0);
    
    graph.adj[3].add(0);
    
    graph.adj[3].add(1);
    
    graph.adj[3].add(4);
    
    graph.adj[3].add(5);
    
    graph.adj[4].add(1);
    
    graph.adj[4].add(3);
    
    graph.adj[4].add(5);
    
    graph.adj[5].add(3);
    
    graph.adj[5].add(4);
    
    System.out.println("图的深度优先遍历:");
    
    dfs(graph, 0, new boolean[graph.size]);
    
    System.out.println("图的广度优先遍历:");
    
    bfs(graph, 0, new boolean[graph.size], new LinkedList());
    
    }
    

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 深度优先遍历

    2020-10-05 11:10:30
    什么是深度优先遍历 深度优先遍历:尽可能深的搜索树的分支 深度优先遍历算法口诀 访问根节点; 对根节点的children挨个进行深度优先遍历。 const tree = { val: 'a', children: [ { val: 'b', children: [ ...

    在这里插入图片描述

    什么是深度优先遍历

    深度优先遍历:尽可能深的搜索树的分支
    

    深度优先遍历算法口诀

    访问根节点;
    对根节点的children挨个进行深度优先遍历。
    
    const tree = {
        val: 'a',
        children: [
            {
                val: 'b',
                children: [
                    {
                        val: 'd',
                        children: []
                    },
                    {
                        val: 'e',
                        children: []
                    }
                ]
            },
            {
                val: 'c',
                children: [
                    {
                        val: 'f',
                        children: []
                    },
                    {
                        val: 'g',
                        children: []
                    }
                ]
            }
        ]
    }
    
    const dfs = (root) => {
        console.log(root.val);
        // root.children.forEach((child) => {dfs(child)});
        root.children.forEach(dfs);
    }
    dfs(tree);
    

    运行结果:

    a b d e c f g 
    
    展开全文
  • 主讲人 李 刚 图的深度优先遍历 C 目 录 ONTENTS 01 深度优先遍历实例演示 深度优先遍历实例演示 1 1 2 3 4 5 6 7 8 9 02 深度优先遍历实现过程 深度优先遍历实现过程 2 操作步骤 V1 V2 V5 V3 V0 V7 V6 V4 V8 在图中...
  • 广度优先遍历和深度优先遍历等js函数
  • 主要介绍了python实现树的深度优先遍历与广度优先遍历,详细分析了树的深度优先遍历与广度优先遍历原理及Python相关实现技巧,需要的朋友可以参考下
  • 主要介绍了JavaScript树的深度优先遍历和广度优先遍历算法,结合实例形式分析了JavaScript树的深度优先遍历、广度优先遍历递归与非递归相关实现技巧,需要的朋友可以参考下
  • 深度优先遍历 广度优先遍历 的实现 深度优先遍历 广度优先遍历 的实现 深度优先遍历 广度优先遍历 的实现
  • 主要介绍了Java实现二叉树的深度优先遍历和广度优先遍历算法,结合实例形式详细分析了二叉树的定义、深度优先遍历与广度优先遍历算法原理与相关操作实现技巧,需要的朋友可以参考下
  • Java实现深度优先遍历和广度优先遍历

    万次阅读 多人点赞 2018-08-16 15:38:33
    深度优先遍历深度优先遍历是图论中的经典算法。其利用了深度优先搜索算法可以产生目标图的相应拓扑排序表,采用拓扑排序表可以解决很多相关的图论问题,如最大路径问题等等。 根据深度优先遍历的特点我们利用Java...

    概念定义

    深度优先遍历:深度优先遍历是图论中的经典算法。其利用了深度优先搜索算法可以产生目标图的相应拓扑排序表,采用拓扑排序表可以解决很多相关的图论问题,如最大路径问题等等。

    根据深度优先遍历的特点我们利用Java集合类的栈Stack先进后出的特点来实现。我用二叉树来进行深度优先搜索。

    深度优先搜索的步骤为:

    (1)、首先节点 1 进栈,节点1在栈顶;

    (2)、然后节点1出栈,访问节点1,节点1的孩子节点3进栈,节点2进栈;

    (3)、节点2在栈顶,然后节点2出栈,访问节点2

    (4)、节点2的孩子节点5进栈,节点4进栈

    (5)、节点4在栈顶,节点4出栈,访问节点4,

    (6)、节点4左右孩子为空,然后节点5在栈顶,节点5出栈,访问节点5;

    (7)、节点5左右孩子为空,然后节点3在站顶,节点3出栈,访问节点3;

    (8)、节点3的孩子节点7进栈,节点6进栈

    (9)、节点6在栈顶,节点6出栈,访问节点6;

    (10)、节点6的孩子为空,这个时候节点7在栈顶,节点7出栈,访问节点7

    (11)、节点7的左右孩子为空,此时栈为空,遍历结束。

     

    广度优先遍历:广度优先遍历是连通图的一种遍历策略,因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域故得名。

    根据广度优先遍历的特点我们利用Java数据结构队列Queue来实现。

    广度优先搜索的步骤为:

    (1)、节点1进队,节点1出队,访问节点1

    (2)、节点1的孩子节点2进队,节点3进队。

    (3)、节点2出队,访问节点2,节点2的孩子节点4进队,节点5进队;

    (4)、节点3出队,访问节点3,节点3的孩子节点6进队,节点7进队;

    (5)、节点4出队,访问节点4,节点4没有孩子节点。

    (6)、节点5出队,访问节点5,节点5没有孩子节点。

    (7)、节点6出队,访问节点6,节点6没有孩子节点。

    (8)、节点7出队,访问节点7,节点7没有孩子节点,结束。

    代码

    二叉树的基础代码:

    /**
     * 二叉树数据结构
     * 
     *
     */
    public class TreeNode {
    	int data;
    	TreeNode leftNode;
    	TreeNode rightNode;
    	public TreeNode() {
    		
    	}
    	public TreeNode(int d) {
    		data=d;
    	}
    	
    	public TreeNode(TreeNode left,TreeNode right,int d) {
    		leftNode=left;
    		rightNode=right;
    		data=d;
    	}
    	
    
    }
    

    广度优先和深度优先遍历算法实现代码:
     

    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.Stack;
    
    /**
     * 深度优先遍历
     * 
     *
     */
    public class DeepFirstSort {
    	public static void main(String[] args) {
    		TreeNode head=new TreeNode(1);
    		TreeNode second=new TreeNode(2);
    		TreeNode three=new TreeNode(3);
    		TreeNode four=new TreeNode(4);
    		TreeNode five=new TreeNode(5);
    		TreeNode six=new TreeNode(6);
    		TreeNode seven=new TreeNode(7);
    		head.rightNode=three;
    		head.leftNode=second;
    		second.rightNode=five;
    		second.leftNode=four;
    		three.rightNode=seven;
    		three.leftNode=six;
    		System.out.print("广度优先遍历结果:");
    		new DeepFirstSort().BroadFirstSearch(head);
    		System.out.println();
    		System.out.print("深度优先遍历结果:");
    		new DeepFirstSort().depthFirstSearch(head);
    	}
    	
    	//广度优先遍历是使用队列实现的
    	public void BroadFirstSearch(TreeNode nodeHead) {
    		if(nodeHead==null) {
    			return;
    		}
    		Queue<TreeNode> myQueue=new LinkedList<>();
    		myQueue.add(nodeHead);
    		while(!myQueue.isEmpty()) {
    			TreeNode node=myQueue.poll();
    			System.out.print(node.data+" ");
    			if(null!=node.leftNode) {
    				myQueue.add(node.leftNode);    //深度优先遍历,我们在这里采用每一行从左到右遍历
    			}
    			if(null!=node.rightNode) {
    				myQueue.add(node.rightNode);
    			}
    			
    		}
    	}
    	
    	//深度优先遍历
    	public void depthFirstSearch(TreeNode nodeHead) {
    		if(nodeHead==null) {
    			return;
    		}
    		Stack<TreeNode> myStack=new Stack<>();
    		myStack.add(nodeHead);
    		while(!myStack.isEmpty()) {
    			TreeNode node=myStack.pop();    //弹出栈顶元素
    			System.out.print(node.data+" ");
    			if(node.rightNode!=null) {
    				myStack.push(node.rightNode);    //深度优先遍历,先遍历左边,后遍历右边,栈先进后出
    			}
    			if(node.leftNode!=null) {
    				myStack.push(node.leftNode);
    			}
    		}
    		
    	}
    
    }
    

    结果为:

     

     

    展开全文
  • 文章目录前言1、深度优先遍历初识1.1深度优先遍历的概念:1.2深度优先遍历举例:2、为什么回溯法要用深度优先遍历?2.1回溯法的概念2.2为什么要用深度优先遍历?3.使用深度优先遍历的过程:3.1使用的相关数据结构:...


    前言

    因为最近算法课将要学习回溯法,而学习回溯法必须要掌握深度优先遍历,刚好挤出一点时间复习(预习)一下深度优先遍历的相关内容。


    1、深度优先遍历初识

    1.1深度优先遍历的概念:

    深度优先遍历(Depth-First-Search)简称DFS,是一种遍历或搜索图的算法,沿着树的深度,竖向的尽可能深的搜索树的分支。
    过程如下:
    1.假如以a为源节点,当与节点相邻的节点都已经被访问过,则回溯到发现a节点的那个节点,直到全部节点都被访问。
    2.如果还存在未被访问的节点,则选择其中一个作为源节点并重复过程1;
    简单来说:
    深度优先遍历的思想就是从上至下,对每一个分支一直往下一层遍历直到这个分支结束,然后返回上一层,对上一层这个分支继续遍历,直到一整棵树完全遍历,因此符合栈后进先出的特点,所以完全可以用栈来实现深度优先遍历。

    1.2深度优先遍历举例:

    比如说如下二叉树:
    在这里插入图片描述
    其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次,后面我会详细列出如何使用栈来进行遍历操作。

    2、为什么回溯法要用深度优先遍历?

    那么为什么回溯法要用深度优先遍历而不用广度优先遍历呢?
    首先我们来看一下回溯法的概念:

    2.1回溯法的概念

    回溯法是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。(此处搬运百度百科)

    2.2为什么要用深度优先遍历?

    回到刚开始的问题,为什么回溯法要用深度优先遍历而不用广度优先遍历?
    由回溯法的概念可以知道,回溯法就是在解决问题的过程中舍去那些达不到目标的解,而深度优先遍历恰好符合这种解决问题的思路,想想,如果使用广度优先遍历,那么就是对于树的按行遍历,那么如果这样遍历,结果就是遍历出整个过程,而无法进行对于明明知道达不到目标的舍去,如果这样的话,反而不如用穷举法(回溯法就是穷举法的优化)。

    3.使用深度优先遍历的过程:

    3.1使用的相关数据结构:

    因为深度优先遍历是先进后出的,所以可以用栈来实现,可以自定义栈,也可以用封装好的stl(stack)对于初学的我们来说还是先要先学会造轮子才能学会用轮子,所以建议先自己写栈的相关操作,等熟练掌握之后再用stack。

    3.2使用深度优先遍历的详细过程

    刚刚列出的那个树:

    在这里插入图片描述

    使用深度优先遍历的步骤如下:
    1、把起始点放入栈中;
    2、重复下述3步骤,直到栈为空为止:
    (1)从栈中访问栈顶的点;
    (2)找出与此点邻接的且尚未遍历的点,进行标记,然后全部放入栈中;
    (3)如果此点没有尚未遍历的邻接点,则将此点从栈中弹出。
    由上面的步骤可知,如果要访问上图树,步骤如下:
    一:将节点A放入栈中标记为已遍历
    在这里插入图片描述
    二:访问栈顶的节点A,找出与此点邻接的点,有B和C,可以选择其中的任意一个(顺序由我们确定,这里我们选择先左后右),我们选择B,标记为已遍历,放入栈中。
    在这里插入图片描述
    三:同样的从栈顶取出节点B,找出与此点邻接的点,有A,D和E,A已经遍历过了,所以排除,这里可以从D和E中选择其中的任意一个(顺序由我们确定,这里我们选择先左后右),我们选择D,标记为已遍历,放入栈中。
    在这里插入图片描述
    四:从栈顶取出节点D,找出与此点邻接的点,有B,但是B已经遍历过了,所以,没有尚未遍历的邻接点,则将此点从栈中弹出。
    在这里插入图片描述
    五:从栈顶取出节点B,找出与此点邻接的点,有A,D和E,A和D已经遍历过了,所以排除,这里我们只能选择E,标记为已遍历,放入栈中。
    在这里插入图片描述
    l六:从栈顶取出节点E,找出与此点邻接的点,有B,但是B已经遍历过了,所以,没有尚未遍历的邻接点,则将此点从栈中弹出。
    在这里插入图片描述
    七:从栈顶取出节点B,找出与此点邻接的点,有A,D和E,但是都已经遍历过了,所以,没有尚未遍历的邻接点,则将此点从栈中弹出。
    在这里插入图片描述

    八:从栈顶取出节点A,找出与此点邻接的点,有B和C,B已经遍历过了,所以排除,这里只能选择C,标记为已遍历,放入栈中。
    在这里插入图片描述
    九:从栈顶取出节点C,找出与此点邻接的点,有A,F,G和H,A已经遍历过了,所以排除,这里从F,G,H中选择,我们选择F,标记为已遍历,放入栈中。
    在这里插入图片描述
    十:从栈顶取出节点F,找出与此点邻接的点,只有C,但是C已经遍历过了,所以,没有尚未遍历的邻接点,则将此点从栈中弹出。
    在这里插入图片描述
    十一:从栈顶取出节点C,找出与此点邻接的点,有A,F,G和H,A和F已经遍历过了,所以排除,这里从G,H中选择,我们选择G,标记为已遍历,放入栈中。
    在这里插入图片描述
    十二:从栈顶取出节点G,找出与此点邻接的点,只有C,但是C已经遍历过了,所以,没有尚未遍历的邻接点,则将此点从栈中弹出。
    在这里插入图片描述
    十三:从栈顶取出节点C,找出与此点邻接的点,有A,F,G和H,A,F和G已经遍历过了,所以排除,这里只能选择H,标记为已遍历,放入栈中。
    在这里插入图片描述

    十四:从栈顶取出节点H,找出与此点邻接的点,只有C,但是C已经遍历过了,所以,没有尚未遍历的邻接点,则将此点从栈中弹出。
    在这里插入图片描述
    十五:相信看到这里都已经明白了,最后再进行两次判定,栈最后为空,而树也遍历完成。

    4、回溯法中深度优先遍历的应用:

    4.1解空间:

    首先了解解空间的概念:
    一个复杂问题的解决方案可以分成多个步骤,而每个步骤都有很多种选择,这些每个步骤的组合构成了这个问题的解空间解空间树。(为什么叫解空间树:因为解空间一般是用树的形式来组织,这也是这里学习深度优先遍历的目的)

    而在解决具体问题的时候,我们进行解空间树的遍历,在遍历过程中,满足问题描述的约束条件的解空间叫可行解,同样我们也可从所有可行解中求出最优解
    我们遇到的问题往往都是求所有的可行解或最优解。
    而解空间树也可以分为子集树排列树
    子集树:顾名思义就是从n个元素的集合中求满足条件的幂集。
    排列树:当所给的问题是确定的n个元素满足某种条件时,相应的解空间树就是排列树。

    在这里插入图片描述

    4.2、剪枝函数

    在求解空间时,如何优化?
    约束函数和限界函数就是为了避免无效的搜索。
    约束函数:在扩展结点处剪除不满足约束条件的路径。
    限界函数:剪去得不到问题解或者最优解的路径。
    这两类函数都称为剪枝函数。

    4.3、回溯法解题的一般步骤:

    (1)针对问题确定解空间树,问题的解空间树至少包含问题的一个可行解或者最优解
    (2)确定结点的扩展搜索规则
    (3)以深度优先方式遍历解空间树,在遍历过程中用剪枝函数来避免无效的遍历,深度优先可以用递归也可以用非递归实现。

    总结

    本次复习了一下基本概念,下面看一下具体题目。

    展开全文
  • JS深度优先遍历和广度优先遍历 深度优先遍历 (DFS) Depth First Search (1)访问顶点v; (2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问; (3)若此时图中尚...
  • C语言实现图的深度优先遍历和广度优先遍历

    千次阅读 多人点赞 2019-11-28 20:29:17
    图的深度优先遍历和广度优先遍历图的遍历深度优先遍历广度优先遍历 图的遍历 从给定图中任意指定的顶点(称为初始点)出发,按照某种搜索方法沿着图的边访问图中所有顶点,使每个顶点仅被访问一次,这个过程称为图的...
  • 二叉树的深度优先遍历和广度优先遍历

    万次阅读 多人点赞 2016-10-07 20:18:15
    二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。要特别注意的是,二叉树的...
  • 文章目录一、图的概述1.1 什么是图1.2 图对比线性表和树1.3 图的常见概念二、图的存储方式2.1 邻接矩阵2.2 邻接表三、图的遍历3.1 图的深度优先遍历3.1.1 什么是深度优先遍历3.1.2 深度优先遍历的步骤3.1.3 深度优先...
  • 邻接矩阵实现图,Java实现数据结构,Java实现图的深度优先遍历,广度优先遍历
  • 图的深度优先遍历 图的深度优先遍历参考 图的深度优先遍历 参考 1、https://blog.csdn.net/todd911/article/details/9191481 2、https://blog.csdn.net/weixin_42109012/article/details/94199335
  • 图的深度优先遍历和广度优先遍历深度优先遍历广度优先遍历 邻接表的形式表示一个图: const graph = { 0: [1,2], 1: [2], 2: [3,0], 3: [3,0] } 深度优先遍历 深度优先遍历就是优先遍历完一条完整路径,和树的...
  • graphTraverse 图的深度优先遍历(Stack)和广度优先遍历(Queue)算法
  • 深度优先遍历和广度优先遍历
  • 广度优先遍历和深度优先遍历广度优先遍历图解代码深度优先遍历图解 广度优先遍历 广度优先遍历是图的一种遍历方式, 它的思想就是遍历这个点相邻的所有的点, 再对这些点进行广度优先遍历. 如下图所示 图解 首先...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 76,343
精华内容 30,537
关键字:

深度优先遍历