直接上代碼
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
歡迎大家批評指正,求交流!!!