图
图的相关知识
- 定义
由集合V和V中不同顶点对的集合E组成,V的成员称为图G的顶点(Vertex),顶点对称为G的边(edge)。 - 有向图与无向图
E中顶点对为有序的,则图为有向图。
E中顶点对为无序的,则图为无向图。 - 无向图
- 邻接:如果一个顶点到另一个顶点存在一条边,则称这两个顶点是邻接的。
- 路径:路径是由不同顶点构造的一个序列,序列的每个顶点都与下一个顶点邻接。
- 环:环是一条至少包含3个顶点的路径,路径上最后一个顶点与第一个顶点邻接。
- 连通的:从任一个顶点到任一个其他顶点之间存在一条路径,则称这个图是连通的(connected)。
- 自由树(free tree)定义为没有环的联通无向图。
- 有向图
- 有向路径(环):在有向图中,要求所有的边或环具有同样的方向,因此沿着一条边或环意味着总是沿着箭头指示的方向移动。这样的路径(环)称为有向路径(环)。
- 强连通:如果从一个顶点到另一个顶点之间存在一条有向路径,则称有向图是强连通的。
- 弱连通:不考虑边的方向且结果得到的无向图是连通的,则称有向图是弱连通的。
计算机表示
一、 集合的表示
定义:有向图G有集合V和对所有v∈V,V的子集Av组成,其中V称为G的顶点集,Av称为与v邻接的顶点集。
- 集合的实现
在数据结构和算法中实现顶点集的两种通用方法
i. 将集合表示成其元素的表。
ii. 位串,对集合中每个潜在的元素保留一个布尔值以指示它是否在集合中
template<int max_size>
struct Set{
bool is_element[max_set];
};
//第一种实现:
template<int max_size>
class Digraph{
int count;
Set<max_size>neighbors[max_sizes];
};
- 邻接表格
//第二种实现:邻接表格
template<int max_size>
class Digraph{
int count;
bool adjacency[max_size][max_size];
};
邻接表
用更复杂的表实现图。
- 基于表的实现
//第三种实现:表
typedef int Vertex;
template<int max_size>
class Digraph{
int count;
List<Vertex>neighbors[max_size];
};
- 链式实现
//第四种实现:链式顶点和边
class Edge;
class Vertex{
Edge* first_edge;
Vertex* next_vertex;
};
class Edge{
Vertex* end_vertex;
Edge* next_edge;
};
class Digraph{
Vertex* first_vertex;
};
信息域
图的许多应用不仅需要在各种表示中说明的邻接信息,而且需要具体到每个顶点或每条边的更多的信息。在链式表示,此信息能作为合适记录内的附加成员包含进来;在顺序表示中,信息是通过将数组元素变成记录包含进来。
图的遍历
深度优先
template<int max_size>
void Digraph<max_size>::depth_first(void(*visit)(Vertex &))const
{
bool visited[max_size];
Vertex v;
for(all v in G)visited[V]=false;
for(all v in G)
if(!visited[v])
traverse(v,visited,visit);
}
void Digraph<max_size>::traverse(Vertex &v,bool visited[],void(*visit)(Vertex &))const
{
Vertex w;
visited[v]=true;
(*visit)(v);
for(all w adjacent to v)
if(!visited[w])
traverse(w,visited,visit);
}
广度优先
template<int max_size>
void Digraph<max_size>::breadth_first(void(*visit)(Vertex &))const
{
Queue q;
bool visited[max_size];
Vertex v,w,x;
for(all v in G) visited[v]=false;
for(all v in G)
if(!visited[v]){
q.append(v);
while(!q.empty()){
q.retrieve(w);
if(!visited[w]){
visited[w]=true;
(*visit)(w);
for(all x adjacent to w)
q.append(x);
}
q.serve();
}
}
}