图的深度优先搜索
描述:
图的深度优先搜索类似于树的先根遍历,是树的先根遍历的推广。即从某个结点开始,先访问该结点,然后深度访问该结点的第一棵子树,依次为第二顶子树。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“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;
}
}