图的广度优先搜索

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

猜你喜欢

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