圖的遍歷有多種方式,但是這裏從數據結構基礎出發,還是隻介紹基礎的兩種方式,深度優先遍歷和廣度優先遍歷。
深度優先遍歷
圖的深度優先搜索(Depth First Search),和樹的前序遍歷比較類似。
它的思想:假設初始狀態是圖中所有頂點均未被訪問,則從某個頂點v出發,首先訪問該頂點,然後依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。 若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重複上述過程,直至圖中所有頂點都被訪問到爲止。
顯然,深度優先搜索是一個遞歸的過程。一言以蔽之:“一路走到頭,不撞南牆不回頭”。
代碼實現(鄰接矩陣):
public void DFSSelf() {
boolean[] beTraversed = new boolean[size];
beTraversed[0] = true;
System.out.print(vertexs[0] + " ");
DFSSelf(0, beTraversed);//從頭節點開始
}
public void DFSSelf(int x, boolean[] beTraversed) {
int y = 0;
while (y <= size - 1) {
if (matrix[x][y] != 0 && beTraversed[y] == false) { //遍歷與當前節點有邊的節點
beTraversed[y] = true;
System.out.print(vertexs[y] + " ");//遍歷
DFSSelf(y, beTraversed);//遞歸進行深度遍歷
}
y++;
}
}
鄰接表(思路完全一樣,只是獲取關係節點的方式不一樣):
public void DFS() {
boolean[] beTraversed = new boolean[size];
beTraversed[getPosition(vertexList[0].ch)] = true;
DFS(beTraversed, vertexList[0]);
}
/**
* 深度優先遍歷
*
* @param beTraversed
* @param temp
*/
public void DFS(boolean[] beTraversed, Vertex temp) {
System.out.print(temp.ch + " ");
beTraversed[getPosition(temp.ch)] = true;
while (temp != null) {
if (beTraversed[getPosition(temp.ch)] == false) {
DFS(beTraversed, vertexList[getPosition(temp.ch)]);
}
temp = temp.next;
}
}
廣度優先遍歷
廣度優先搜索算法(Breadth First Search),又稱爲”寬度優先搜索”或”橫向優先搜索”,簡稱BFS。
它的思想是:從圖中某頂點v出發,在訪問了v之後依次訪問v的各個未曾訪問過的鄰接點,然後分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於後被訪問的頂點的鄰接點被訪問,直至圖中所有已被訪問的頂點的鄰接點都被訪問到。如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作爲新的起始點,重複上述過程,直至圖中所有頂點都被訪問到爲止。
換句話說,廣度優先搜索遍歷圖的過程是以v爲起點,由近至遠,依次訪問和v有路徑相通且路徑長度爲1,2…的頂點。
代碼實現(鄰接矩陣):
public void BFSSelf() {
boolean[] beTraversed = new boolean[size];
beTraversed[0] = true;
System.out.print(vertexs[0] + " ");
BFSSelf(0, beTraversed, new LinkedList<>());
}
/**
* 廣度優先搜索遍歷
*
* @param x
* @param beTraversed
*/
public void BFSSelf(int x, boolean[] beTraversed, LinkedList<Character> list) {
int y = 0;
while (y <= size - 1) {
if (matrix[x][y] != 0 && beTraversed[y] == false) { //依次將與當前節點有聯繫的節點遍歷,然後入隊。
beTraversed[y] = true;
System.out.print(vertexs[y] + " ");
list.add(vertexs[y]);
}
y++;
}
if (!list.isEmpty()) { //出隊進行遞歸操作
Character node = list.pop();
int pos = getPosition(node);
BFSSelf(pos, beTraversed, list);
}
}
鄰接表
public void BFS(){
boolean[] beTraversed = new boolean[size];
beTraversed[getPosition(vertexList[0].ch)] = true;
System.out.print(vertexList[0].ch+" ");
int startPos = getPosition(vertexList[0].ch);
BFS(startPos,beTraversed);
}
/**
* 廣度優先搜素遍歷
* @param beTraversed
*/
public void BFS(int x,boolean[] beTraversed){
Vertex temp = vertexList[x];
LinkedList<Vertex> list = new LinkedList<>();
while(temp!=null){
if(beTraversed[getPosition(temp.ch)] == false){
System.out.print(temp.ch+" ");
beTraversed[getPosition(temp.ch)] = true;
list.add(vertexList[getPosition(temp.ch)]);
}
temp = temp.next;
}
while(!list.isEmpty()){
Vertex node = list.pop();
int pos = getPosition(node.ch);
BFS(pos,beTraversed);
}
}