图的深度优先搜索

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


猜你喜欢

转载自blog.csdn.net/qq_36734025/article/details/78942711