其他一些概念:
完全图:在由n个顶点组成的无向图中,若有N(N-1)/2条边,则成为无向完全图。(也就是说任意两个点都有路径)
边的权重:权重表示对边赋予的权值。
邻接顶点:如果两个顶点之间有边,则这两个顶点就互为邻接顶点。
度:与顶点v关联的边的数目称为顶点v的度。
路径:在图G=(V,E)中,若从顶点v1出发,沿着边经过若干顶点v2、v3…到v8,则(v1,v2…v8)就是顶点v1到顶点v8的路径。
连通图:在无向图中,若任意两个顶点之间都有路径,则此图就是连通图。
强连通图:在有向图中,若每一对顶点之间都存在路径,则称此图就是强连通图。
图的存储:
图由顶点和边组成,所以在存储的时候我们不仅要存储图的顶点,还要存储图的边。图的存储有两种方式,邻接矩阵和邻接表。
图的遍历:
图的遍历右两种方式,深度优先遍历(DFS)和广度(BFS)优先遍历。深度优先遍历就是沿着一条路径一直走到底,直到走不下去的时候再返回上一个路口寻找一条没走过的路径再走。广度优先遍历是一种层层递进的思想,以起点为中心,一层一层的访问。不过对于图来说,不管是哪种遍历,我们都可能再次遇到已经访问过的结点,所以在对图遍历的时候我们还需要用一个辅助数组来标记哪些结点已经访问过了,哪些结点还没有访问过。
深度优先遍历(DFS):
void DFS(const V& src) //深度优先遍历
{
vector<bool> visited(_vertax.size(),false);
_DFS(GetIndex(src),visited);
for (size_t i = 0; i < visited.size(); ++i) //如果图不是连通图的话
{
if (visited[i]==false)
_DFS(i, visited);
}
}
void _DFS(size_t src,vector<bool>& visited)
{
Node* cur = _tables[src];
printf("%s:->", _vertax[src].c_str());
visited[cur->_src] = true; //将已经访问过的结点标记起来
while (cur)
{
if (visited[cur->_dst] == false)
_DFS(cur->_dst, visited);
cur = cur->_next;
}
}
广度优先遍历(BFS):
void BFS(const V& src)
{
size_t index = GetIndex(src);
vector<bool> visited(_vertax.size(),false);
queue<size_t> q;
q.push(index); //将起点的坐标入队
while (!q.empty())
{
size_t front = q.front();
q.pop();
cout << _vertax[front].c_str() << "->";
visited[front] = true;
Node* cur = _tables[front];
while (cur)
{
if (visited[cur->_dst] == false)
{
q.push(cur->_dst);
visited[cur->_dst] = true; //如果这个元素已经入队了,则就标记为true
}
cur = cur->_next;
}
}
}