在本次实验的任务三,社交网络中,涉及到了关于图的广度优先算法。在上学期中,对本算法已经有了学习,但在完成本次任务时仍是花费了相对较多的不必要的时间。因此在此对深度优先搜索算法和广度优先搜索算法做一个系统的总结。
一.图的遍历
1.定义
从图中的某一顶点出发,对图中所有的顶点访问一次且仅访问一次。
2.关键问题
(1)在图中,如何选取遍历的其实顶点?
从编号最小的顶点开始。
(2)从某个起点开始可能到达不了所有其它的顶点,怎么办?
多次调用从某顶点出发遍历图的算法。
(3)图中可能存在回路,且图的任一顶点都可能与其它顶点相通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过得顶点。如何避免某些顶点可能会被重复访问?
设计标记数组,标记访问过的顶点。
(4)在图中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,如何选取下一个要访问的顶点?
广度优先搜索和广度优先搜索。
二.广度优先搜索
1.简介
广度优先搜索(Breadth First Search),又叫做BFS,类似于树的层序遍历。尽可能在横向上进行搜索,并使“先被访问的顶点的邻接点”先于“后被访问的邻接点”被访问,故称广度优先搜索或先广搜索。
2.定义
设图G的初态是所有顶点都False,在G中任选一个顶点v为源点,则广度优先搜索可定义为:
①首先访问出发点v,并将其标记为True;
②接着依次访问所有与v相邻的顶点w1,w2……wt;
③然后依次访问与w1,w2……wt相邻的所有未被访问的点;
④以此类推,直至图中所有与源点v有路相通的顶点都以访问过为止;
⑤此时,从v开始的搜索结束,若G是连通的,则遍历完成;否则在G中另选一个尚未被访问的顶点作为新的源点,继续上述搜索过程,直到G中的所有顶点均已访问为止。
例如:下图中的无向图,从1开始进行广度优先搜索,则遍历序列应为:125734689.
3.实现步骤
1.初始化队列Q;
2.访问顶点v;visited[v]=1;顶点v入队Q;
3.while(队列Q非空)
3.1v=队列Q的队头元素出队;
3.2w=顶点v的第一个邻接点;
3.3while(w存在)//访问v的所有邻接点
3.3.1如果w未被访问,则
访问顶点w;visited[w]=1;顶点w入队列Q;
3.3.2w=顶点v的下一个邻接点。
4.实际应用
Dijkstra单源最短路径算法和Prim最小生成树算法。
三.深度优先搜索
1.简介
深度优先搜索(Depth First Search),又叫做DFS,类似于树结构的先序遍历。尽可能对纵深方向上进行搜索,故称深度优先搜索或先深搜索。
2.定义
设图G的初态是所有顶点都False,在G中任选一个顶点v为源点,则深度优先搜索可定义为:
①首先访问出发点v,并将其标记为True;
②然后,从v出发。依次考察与v相邻的顶点w;若w为False,则以w为新的出发点递归地进行深度优先搜索,直到图中所有与源点v有路径相同的顶点均被访问为止;
③若此时图中仍有未被访问过的顶点,则选另一个False顶点作为新的搜索起点,重复上述过程,指导图中所有的顶点都被访问为止。
例如:下图中的无向图,从1开始进行深度优先搜索,则遍历序列应为:123456789.
3.实现步骤
1.所有顶点标记为visited[v]={0,……};
2.访问顶点v;visited[v]=1;
3.w=顶点v的第一个邻接点;
4.while(w存在)
4.1if(w未被访问过)
从顶点w出发递归地执行该算法;
4.2w=顶点v的下一个邻接点。
4.实际应用
达到被搜索结构的叶结点;判断是否有环。