1. 程式人生 > >每日一題——圖的遍歷(BFS 和DFS)

每日一題——圖的遍歷(BFS 和DFS)

  • 題目描述

從鍵盤接收有向圖的頂點集,弧集,建立有向圖,並完成下列任務:

(1)計算結點的出度、入度以及度;

(2) 從第一個頂點出發,求一個深度優先遍歷序列;

(3) 從第一個頂點頂點出發,求一個廣度優先遍歷序列。

注意:以使用者輸入各個頂點的順序為頂點的序號。
在深度和廣度優先遍歷中,優先選擇序號小的頂點。

  • java程式碼
public class Gragh
{
	AdjMatrix G;
	
	private boolean[] visited;

	public Gragh(){
		Scanner sc = new Scanner(System.in);
		System.out.println("輸入頂點數和邊數:");
		int vertexnum = sc.nextInt();
		int arcnum = sc.nextInt();
		
		G = new AdjMatrix(vertexnum,arcnum);
		
		System.out.println("輸入頂點資訊:");
		for(int i = 1;i <= G.vertexnum;i++)
		{
			G.vertex[i] = sc.next().charAt(0);
		}
		
		//初始化鄰接矩陣
		for(int i = 1;i <= G.vertexnum;i++)
		{
			for(int j = 1;j <= G.vertexnum;j++)
			{
				G.arcs[i][j] = 0;
			}
		}
		
		//建立有向圖
		System.out.println("輸入頭和尾頂點:");
	    int head = 0,tail = 0;
	    for(int i = 0;i < G.arcnum;i++)
	    {
	    	char vertex_head = sc.next().charAt(0);
		    char vertex_tail = sc.next().charAt(0);
	    	for(int j = 1;j <= G.vertexnum;j++)
	    	{
		    	if(G.vertex[j] == vertex_head)
		    	{
		    		head = j;
		    		for(int k = 1;k <= G.vertexnum;k++)
		    		{
				        if(G.vertex[k] == vertex_tail)
				    		tail = k;
				    }
			    }
		    }
	    	G.arcs[head][tail] = 1;
	    }
		sc.close();
	}
	
	/*
	 * 結點的出度、入度、度
	 */
	public void degree() {
		for(int i = 1;i <= G.vertexnum;i++)
		{
			int count_out = 0; int count_in = 0;int count = 0;
			for(int j = 1;j <= G.vertexnum;j++)
			{
				if(G.arcs[j][i] == 1)
					count_in++;
				if(G.arcs[i][j] == 1)
					count_out++;
				count = count_in + count_out;
			}
			System.out.println(G.vertex[i] + " " + count_out + " " + count_in + " "
					+ count);
		}
		
	}
	
	private void DFS(int start) {
		visited = new boolean[G.vertexnum + 1];
		Stack<Integer> s = new Stack<>();
		s.push(start);
		System.out.print(G.vertex[start]);
		visited[start] = true;
		while(!s.empty())
		{
			int top = s.peek();
			boolean is_push = false;
			for(int i = 1;i <= G.vertexnum;i++)
			{
				if(G.arcs[top][i] == 1 && visited[i] == false) 
				{
					System.out.print(G.vertex[i]);
					visited[i] = true;
					s.push(i);
					is_push = true;
					break;
				}
			}
			if(is_push == false) {
				s.pop();
			}
		}	
	}
	
	public void DFSTraverse() {
		visited = new boolean[G.vertexnum + 1];
		for(int i = 1;i <= G.vertexnum;i++)
		{
			if(visited[i] == false)
				DFS(i);
		}
	}
	
	private void BFS(int start) {
		visited = new boolean[G.vertexnum + 1];
		Queue<Integer> q = new LinkedList<>();
		System.out.print(G.vertex[start]);
		visited[start] = true;
		q.add(start);
		while(!q.isEmpty())
		{
			int top = q.poll();
			for(int i = 1;i <= G.vertexnum;i++)
			{
				if(G.arcs[top][i] == 1 && visited[i] == false) 
				{
					System.out.print(G.vertex[i]);
					visited[i] = true;
					q.add(i);
				}
			}
		}	
	}
	public void BFSTraverse() {
		visited = new boolean[G.vertexnum + 1];
		for(int i = 1;i <= G.vertexnum;i++)
		{
			if(visited[i] == false)
				BFS(i);
		}
	}
	
	/*
	 * 列印有向圖
	 */
	public void showGragh(){
		System.out.print("   ");
		for (int i = 1; i <= G.vertexnum; i++)
		{//列印頂點資訊
			System.out.print(G.vertex[i] + " ");
		}
		System.out.println();
		for (int i = 1; i <= G.vertexnum; i++)
		{//列印鄰接矩陣
			System.out.print(G.vertex[i] + "  ");
			for (int j = 1; j <= G.vertexnum; j++)
			{
				System.out.print(G.arcs[i][j] + " ");
			}
			System.out.println();
		}
	}
}
class AdjMatrix{
	final int MAX_VERTEX = 20;                              //最大頂點個數
	int[][] arcs = new int[MAX_VERTEX][MAX_VERTEX];         //邊資訊
	char[] vertex = new char[MAX_VERTEX];                   //頂點資訊
	int vertexnum;               //頂點數
	int arcnum;                  //邊數
	AdjMatrix(int vertexnum,int arcnum) {
		this.vertexnum = vertexnum;
		this.arcnum = arcnum;
	}
}
  • 測試函式
public static void main(String[] args)
	{
		Gragh gragh = new Gragh();
		gragh.showGragh();
		gragh.degree();
		gragh.DFSTraverse();
		System.out.println();
		gragh.BFSTraverse();
	}

  • 執行結果

輸入頂點數和邊數:
5 7
輸入頂點資訊:
A B C D E
輸入頭和尾頂點:
A B
A E
B C
C D
D A
D B
E C
列印矩陣:
A B C D E
A 0 1 0 0 1
B 0 0 1 0 0
C 0 0 0 1 0
D 1 1 0 0 0
E 0 0 1 0 0
各頂點出度、入度、度:
A 2 1 3
B 1 2 3
C 1 2 3
D 2 1 3
E 1 1 2
DFS遍歷:
ABCDE
BFS遍歷:
ABECD