时间复杂度的对比分析
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适用于资源受限的场合
-广度优先按照“层次的方式”对顶点进行访问
-广度优先算法的核心是队列的使用