图的深度优先搜索
描述:
图的深度优先搜索类似于树的先根遍历,是树的先根遍历的推广。即从某个结点开始,先访问该结点,然后深度访问该结点的第一棵子树,依次为第二顶子树。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“A”至“Z”中的若干字符表示,且要求结点的访问顺序根据“A”至“Z”的字典顺序进行访问。例如有如下图:
如果要求从H开始进行深度优先搜索,则搜索结果为:H->A->K->U->E.
输入:
输入只包含一个测试用例,第一行为一个自然数n,表示顶点的个数,第二行为n个大写字母构成的字符串,表示顶点,接下来是为一个n*n大小的矩阵,表示图的邻接关系。数字为0表示不邻接,否则为相应的边的长度。
最后一行为一个字符,表示要求进行深度优先搜索的起始顶点。
输出:
用一行输出深度优先搜索结果,起始点为给定的顶点,各顶点之间用一个空格隔开。要求同一层顶点的邻接点的访问顺序按“A”至“Z”的字典顺序。
样例输入:
5
HUEAK
0 0 2 3 0
0 0 0 7 4
2 0 0 0 0
3 7 0 0 1
0 4 0 1 0
H
样例输出:
H A K U E
算法提示:首先根据图的邻接矩阵创建邻接表(采用后插法,即每个边结点都插入到最后一个位置),然后结合栈结构完成图的深度优先遍历
package graph; import java.util.Scanner; import java.util.Stack; public class DFS { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int i,j,p; String s = sc.nextLine(); s = sc.nextLine(); Graph g = new Graph(n,s); for(i = 0 ;i<n;i++) { for(j = 0 ;j<n;j++) { p = sc.nextInt(); if(p!=0) { EdgeNode e = new EdgeNode(j); g.insert(e,i); } } } String s1 =sc.nextLine(); s1=sc.nextLine(); // System.out.println(s1); g.DFS(s.indexOf(s1.charAt(0))); } } class Graph { //邻接表 //顶点数 AdjacencyList[] AdjList; int n; public Graph(int n, String s) { int i; AdjList = new AdjacencyList[n]; this.n= n; for(i=0;i<n;i++) { AdjList[i] = new AdjacencyList(s.charAt(i)); } } //尾插法 public void insert(EdgeNode e, int i) { EdgeNode p = AdjList[i].firstedge; if(AdjList[i].firstedge == null) { AdjList[i].firstedge = e; return ; } while(p.next!=null) { p=p.next; } p.next = e; } //根据设定的开始的顶点位置(start>=1)进行深度优先遍历 /** * 1.需要一个标记数组 * 2.访问完一个顶点之后,把和它邻接的点(且未被访问的点)全部入栈 * 抛出一个元素,然后访问它所有的邻接点 * @param start */ public void DFS(int start) { int i,t; int[] flag = new int[n]; for(i=0;i<n;i++) flag[i]=0; Stack<Integer> s = new Stack<Integer>(); s.push(start);//类似于树的先序遍历的非递归代码,先把 while(!s.isEmpty()) { t= s.pop(); if(flag[t] == 0)//未被遍历过的顶点 { System.out.print(AdjList[t].data+" "); flag[t] = -1;//遍历过的 插旗 EdgeNode e = AdjList[t].firstedge; while(e!=null) { if(flag[e.vertex]==0)//未被访问过的顶点 s.push(e.vertex); e = e.next; } } } } } //adjacent邻接的 list表 邻接表 adjcency邻接 class AdjacencyList { char data;//顶点数据 EdgeNode firstedge; public AdjacencyList(char data) { this.data = data; firstedge = null; } } //顶点的位置, 下一个边 class EdgeNode { int vertex; EdgeNode next; public EdgeNode(int vertex) { this.vertex = vertex; next =null; } }