資料結構 筆記:圖的遍歷(BFS)
阿新 • • 發佈:2018-12-01
時間複雜度的對比分析
MatrixGraph | ListGraph | |
addVertex | - | O(n) |
removeVertex | - | O(n^2) |
getVertex | O(1) | O(n) |
setVertex | O(1) | O(n) |
getAdjacent | O(n) | O(n) |
getEdge | O(1) | O(n) |
setEdge | O(1) | O(n) |
removeEdge | O(1) | O(n) |
vCount | O(1) | O(1) |
eCount | O(1) | O(n) |
ID | O(n) | O(n^2) |
OD | O(n) | O(n) |
小結論
-MatrixGraph使用於記憶體資源富足的場合(效能較好)
-ListGraph適用於記憶體資源受限的場合(節省空間)
圖的遍歷
-從圖中的某一頂點觸發,沿著一些邊訪問圖中的其他頂點,使得每個頂點最多被訪問一次
ps:從某個頂點出發進行遍歷,不一定能夠訪問到圖中的所有頂點
-廣度優先(Breadth First Search)
·以二叉樹層次遍歷的思想對圖進行遍歷
-深度優先(Depth First Search)
·以二叉樹先序遍歷的思想對圖進行遍歷
廣度優先演算法
-原料:class LinkQueue<T>;
-步驟:
1.將其實頂點壓入佇列中
2.隊頭頂點v彈出,判斷是否已經標記(標記:轉2,為標記:轉3)
3.標記頂點v,並將頂點v的鄰接頂點壓入佇列中
4.判斷佇列是否為空(非空:轉2,空:結束)
廣度優先演算法示列
template<typename T>
DynamicArray<T>* toArray(LinkQueue<T>& queue)
{
DynamicArray<T>* ret = new DynamicArray<T>(queue.length());
if(ret != NULL)
{
for(int i = 0;i<ret->length();i++,queue.remove())
{
ret->set(i,queue.front());
}
}
else
{
//丟擲異常
}
return ret;
}
SharedPointer<Array<int>> BFS(int i)
{
DynamicArray<int>* ret = NULL;
if( (0 <= i) && (i < vCount()))
{
LinkQueue<int> q;
LinkQueue<int> r;
DynamicArray<bool> visited(vCount());
for(int i = 0;i<visited.length();i++)
{
visited[i] = false;
}
q.add(i);
while(q.length() > 0)
{
int v = q.front();
q.remove();
if(!visited[v])
{
SharedPointer<Array<int>> aj = getAdjacent(v);
for(int j = 0;j<aj->length();j++)
{
q.add((*aj)[j]);
}
r.add(v);
visited[v] = true;
}
}
ret = toArray(r);
}
else
{
//丟擲異常
}
return ret;
}
總結:
-MatrixGraph適用於資源富足的場合
-ListGraph適用於資源受限的場合
-廣度優先按照“層次的方式”對頂點進行訪問
-廣度優先演算法的核心是佇列的使用