2021/10/1+10/2 圖Graph的建立 + dfs + bfs
阿新 • • 發佈:2021-10-02
2021/10/1 圖Graph
為什麼要有圖:
當我們需要表示多對多的關係時。
圖是一種資料結構,其中結點可以具有零個或多個相鄰元素。二個結點之間的連線為邊
術語介紹
1)頂點(vertex)又叫結點
2)邊(edge)
3)路徑
4)無向圖、有向圖
5)頂點的度:是指依附於某頂點v的邊數,通常記為TD(v)
使用集合表示圖:
- 無向圖:E = {(v1,v2),(v1,v4),(v2,v3),(v3,v4),(v3,v5)}
- 有向圖:G = {<v1,v2>,<v1,v3>,<v3,v4>,<v4,v1>}
1、圖的表示方式
1、鄰接矩陣
2、鄰接表
2、圖的程式碼實現
思路:1、使用List儲存頂點資訊
2、使用二維陣列儲存節點於節點之間的資訊
3、圖的遍歷
dfs:depth first search 深度優先搜尋
- 類似樹的先根遍歷
bfs:breadth first search 廣度優先演算法
- 類似樹的按參差遍歷
[0, 1, 1, 0, 0]
[1, 0, 1, 1, 1]
[1, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
[0, 1, 0, 0, 0]
具體程式碼和八皇后很類似:
所以我們在思考使用DFS進行解決問題的時候需要思考這兩個問題:是否有條件不成立的資訊(w=-1),是否有條件成立的資訊(for迴圈結束)
getFirstNeighbor 結合矩陣 指獲得第一個相鄰節點。
getNextNeighbor 指獲得下一個相鄰節點
public void dfs(int i){ System.out.println(getNodeNameByIndex(i)); isVisited[i]= true; /** * 很重要的程式碼 w!=-1 表明沒有與他相連的結點了 * for迴圈的結束表明遍歷完了 */ for (int w = getFirstNeighbor(i); w!=-1 ; w=getNextNeighbor(i,w)) { if (!isVisited[w]){ dfs(w); } } } public int getFirstNeighbor(int index){ for (int i = 0; i < vertexList.size(); i++) { if(edges.get(index).get(i)==1){ return i; } } return -1; } public int getNextNeighbor(int i,int j){ for (int k = j+1; k < vertexList.size(); k++) { if (edges.get(i).get(k)==1){ return k; } } return -1; }
2021/10/2 bfs
1、廣度優先遍歷基本思想:
圖的廣度優先搜尋(Broad First Search)
2、程式碼實現:
public void bfsV2(int i){
int u ;// 表示佇列頭節點對應的下標
int w; // 表示鄰結點下標
System.out.println(getNodeNameByIndex(i));
deque.add(i);
isAdded[i] = true;
while(!deque.isEmpty()){
// 取出佇列頭
u = (int) deque.pop();// 獲取鄰結點
for ( w= getFirstNeighbor(u); w !=-1 ; w=getNextNeighbor(u,w)) {
// 未被加入佇列
if(isAdded[w]==false){
System.out.println(getNodeNameByIndex(w));
isAdded[w] = true;
deque.add(w);
}
}
}
}
/**
* 可能會有非連通結點的情況 所以我們需要遍歷
*/
public void bfsV2(){
for (int i = 0; i < vertexList.size(); i++) {
if(isAdded[i]==false){
bfsV2(i);
}
}
}
3、dfs與bfs之間的比較
4、圖的總結
1、根據圖的圖形,建立鄰接矩陣
2、dfs。回朔+遞迴 縱向
3、bfs。佇列。橫向