图的广度优先搜索
描述:
图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接点的邻接点。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“A”--“Z”中的若干字符表示,且要求结点的访问顺序要求根据由“A”至“Z”的字典顺序进行访问。例如有如下图:
描述:
图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接点的邻接点。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“A”--“Z”中的若干字符表示,且要求结点的访问顺序要求根据由“A”至“Z”的字典顺序进行访问。例如有如下图:
如果要求从H开始进行广度优先搜索,则搜索结果为:H->A->E->K->U.
输入:
输入只包含一个测试用例,第一行为一个自然数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 E K U
思路:
用java类库实现
linkedlist 实现了queue接口
offer追加元素
poll删除队头
peek 获取队头
size
图的广度优先搜索类似于树的层序遍历,可以通过队列来实现
首先构造邻接表,然后开始BFS实现:
BFS Queue
用flag记录顶点是否
没有被遍历过,才遍历
遍历过的注意清一下标记
然后把邻接的没有遍历的入队列。根据队列的特性,先进先出,这里把邻接的(也就是下一层的)入队,但是要等到这一层的所有结点全部出队之后才会输出邻接的。
package easyProgram; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; import java.util.Stack; public class BFS { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int i,j; int n = sc.nextInt(); String s = sc.nextLine(); s = sc.nextLine(); // System.out.println(s); int c; Gra g = new Gra(s,n); int x=0; for(i =0;i<n;i++) { for(j = 0 ;j<n;j++) { c = sc.nextInt(); if(c!=0) { Edge e = new Edge(j); g.insert(e, i); } } } /*for(i = 0;i<n;i++) { System.out.print(g.AdjList[i].ch+":"); Edge e = g.AdjList[i].first; while(e!=null) { System.out.print(g.AdjList[e.vertex].ch+" "); e = e.next; } System.out.println(); }*/ String sr = sc.nextLine(); sr = sc.nextLine(); g.BFS(s.indexOf(sr.charAt(0))); // g.DFS(s.indexOf(sr.charAt(0))); } } class Gra{ AdjListNode[] AdjList; int n; public Gra(String s,int n) { this.n = n; AdjList = new AdjListNode[n]; for(int i =0;i<n;i++) AdjList[i] = new AdjListNode(s.charAt(i)); } //等下再写一遍 public void insert(Edge e,int i) { //如果第一个邻接点比e的顶点的ch值大,或者第一个邻接点不存在 if(AdjList[i].first==null||AdjList[i].ch>AdjList[e.vertex].ch) { e.next = AdjList[i].first; AdjList[i].first = e; return ; } Edge p = AdjList[i].first; //插入在比e大的前面 又由于单链表的特性,需记录要插入位置的前一个结点 while(p.next!=null&&AdjList[p.next.vertex].ch<AdjList[e.vertex].ch) { p = p.next; } //如果没有到链表尾部,需链接上后面的结点 if(p!=null) { e.next = p.next; } p.next =e; } public void BFS(int start) { int[] flag = new int[n]; Queue<Integer> q = new LinkedList<Integer>(); q.offer(start); while(!q.isEmpty()) { int t = q.poll(); if(flag[t] ==0) { System.out.print(AdjList[t].ch+" "); flag[t] = -1; Edge e = AdjList[t].first; while(e!=null) { if(flag[e.vertex]==0) { q.offer(e.vertex); } e=e.next; } } } System.out.println(); } public void DFS(int start) { int[] flag = new int[n]; Stack<Integer> s = new Stack<Integer>(); s.push(start); while(!s.isEmpty()) { int t = s.pop(); if(flag[t] == 0) { System.out.print(AdjList[t].ch+" "); Edge e = AdjList[t].first; flag[t] =-1; while(e!=null) { if(flag[e.vertex] == 0) { s.push(e.vertex); } e = e.next; } } } } } class AdjListNode{ char ch; Edge first; public AdjListNode(char ch) { this.ch = ch; first = null; } } class Edge{ int vertex; Edge next; public Edge(int vertex) { this.vertex = vertex; next =null; } }