Java實現圖的深度優先搜索和廣度優先搜索(無向圖和有向圖)

用鄰接矩陣實現圖的深度優先搜索和廣度優先搜索

直接上代碼

package mytest;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class BFS_DFS{
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int m = in.nextInt();
		int n = in.nextInt();
		int[][] nums = new int[n][2];
		for(int i = 0; i < n; i++) {
			nums[i][0] = in.nextInt();
			nums[i][1] = in.nextInt();
		}
		Graph g = new Graph(m, nums, 0);
		Deep d = new Deep();
		System.out.print("深度優先搜索的順序爲:");
		d.DFSTraverse2(g);
		// 注意:不要連續搜索同一個圖,因爲第一次搜素已經將圖頂點的標誌位設爲已讀
//		Board b = new Board();
//		System.out.print("廣度優先搜索的順序爲:");
//		b.boradTraverse2(g);
	}
}

class Board{
	int d = 0;  // 有向圖的層數
	/*
	 * 無向圖廣度優先搜索
	 * @param 圖
	 */
	public void boradTraverse1(Graph g) {
		Queue<Node> q = new LinkedList<Node>();
		for(int i = 0; i < g.vexnum; i++) {
			if(g.nodeList[i].isVisited() == false) {
				q.add(g.nodeList[i]);
				g.nodeList[i].setVisited(true);
				// 對頂點i的函數操作
				System.out.print(g.nodeList[i].getNum()+" ");
				//d ++;
			}
			while(! q.isEmpty()) {
				int j = q.poll().getNum() - 1;
				for(int k = 0; k < g.vexnum; k++) {
					if(g.graph[j][k] == 1 && g.nodeList[k].isVisited() == false) {
						g.nodeList[k].setVisited(true);
						// 對頂點k的函數操作
						System.out.print(g.nodeList[k].getNum()+" ");
						q.add(g.nodeList[k]);
					}
				}
			}
		}
	}
	
	/*
	 * 有向圖廣度優先搜索,從頂點入度爲0的頂點開始
	 * @param 圖
	 */
	public void boradTraverse2(Graph g) {
		Queue<Node> q = new LinkedList<Node>();
		g.setInNode();
		for(int i = 0; i < g.vexnum; i++) {
			if(g.inNode[i] == 0) {
				q.add(g.nodeList[i]);
				g.nodeList[i].setVisited(true);
				// 對頂點i的函數操作
				System.out.print(g.nodeList[i].getNum()+" ");
			}
		}
		d = 0;
		while(! q.isEmpty()) {
			int len = q.size();
			for(int i = 0; i < len; i++) {
				int j = q.poll().getNum() - 1;
				for(int k = 0; k < g.vexnum; k++) {
					if(g.graph[j][k] == 1 && g.nodeList[k].isVisited() == false) {
						q.add(g.nodeList[k]);
						g.nodeList[k].setVisited(true);
						// 對頂點k的函數操作
						System.out.print(g.nodeList[k].getNum()+" ");
						
					}
				}
			}
			d++;
		}
	}
}

class Deep{
	public int count = 0;  // 搜索次數
	/* 從第n個節點開始對圖進行深度優先遍歷
	 * @param 圖
	 * @param 第x個節點
	 */
	private void DFS(Graph g, int x) {
		System.out.print(g.nodeList[x].getNum()+" ");
		g.nodeList[x].setVisited(true);
		
		// 此處添加對頂點x的訪問函數
		for(int i = 0; i < g.vexnum; i++) {
			if((g.graph[x][i] == 1) && (g.nodeList[i].isVisited() == false)) {
				DFS(g, i);	
			}
		}
	}
	/*
	 * 無向圖
	 * 全局深度優先搜索
	 * @param 圖
	 */
	public void DFSTraverse1(Graph g) {
		for(int i = 0; i < g.vexnum; i++) {
			if(g.nodeList[i].isVisited() == false) {
				DFS(g, i);
				count++;
				//System.out.println(count);
			}
		}
	}
	/*
	 * 有向圖,從入度爲0的頂點開始
	 * 全局深度優先搜索
	 * @param 圖
	 */
	public void DFSTraverse2(Graph g) {
		g.setInNode();
		for(int i = 0; i < g.vexnum; i++) {
			if(g.nodeList[i].isVisited() == false && g.inNode[i] == 0) {
				DFS(g, i);
				count++;
				//System.out.println(count);
			}
		}
	}
}

// 圖類
class Graph{
	public int[][] graph;  // 鄰接矩陣
	public int vexnum;  // 頂點數
	public Node[] nodeList;  // 頂點數組
	public int flag;  // 0-有向圖,1-無向圖
	public int[] inNode;  // 有向圖各頂點入度
	public int[] outNode;  // 有向圖各頂點出度
	// 頂點以1,2,3.。。進行編號
	public Graph(int vexnum, int[][] nums, int flag) {
		this.vexnum = vexnum;
		this.flag = flag;
		graph = new int[vexnum][vexnum];
		for(int i = 0; i < nums.length; i++) {
			addEdge(nums[i][0]-1, nums[i][1]-1);
		}
		nodeList = new Node[vexnum];
		for(int i = 0; i < vexnum; i++) {
			nodeList[i] = new Node(i+1, false);
		}
	}
	
	public void addEdge(int x, int y) {
		if(x == y || x > vexnum || y > vexnum)
			return;
		else {  // 無向圖
			graph[x][y] = 1;
			graph[y][x] = flag; 
		}
		
	}
	
	/*
	 * 獲取有向圖入度爲0的頂點
	 */
	public void setInNode() {
		inNode = new int[vexnum];
		for(int i = 0; i < vexnum; i++) {
			int j;
			for(j = 0; j < vexnum; j++) {
				if(graph[j][i] == 1)
					inNode[i]++;
			}
		}
	}
	
	/*
	 * 獲取有向圖出度爲0的頂點
	 */
	public void setOutNode() {
		outNode = new int[vexnum];
		for(int i = 0; i < vexnum; i++) {
			int j;
			for(j = 0; j < vexnum; j++) {
				if(graph[i][j] == 1)
					outNode[i]++;
			}
		}
	}
}
// 頂點類
class Node{
	public int num;  // 頂點編號
	public boolean visited;  // 是否訪問過,true-已訪問
	public Node(int num, boolean visited) {
		this.num = num;
		this.visited = visited;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public boolean isVisited() {
		return visited;
	}
	public void setVisited(boolean visited) {
		this.visited = visited;
	}
}

輸入測試

第一行:m-圖的頂點個數,n-邊的條數;
後面n行:每行兩個數,x,y,表示x到y有邊(有向圖的話方向是x->y)。
注意:不要連續搜索同一個圖,因爲第一次搜索已經將圖頂點的標誌位設爲已讀。
輸入節點從1開始往後編號。
8 9
1 2
2 4
4 8
8 5
5 2
1 3
3 6
6 7
7 3
深度優先搜索的順序爲:1 2 4 8 5 3 6 7 

歡迎大家批評指正,求交流!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章