1.相关概念

G=(V;E)  顶点和边的关系

顶点的总数n,边的总数e

(V,V)为邻接关系,(V,E)为关联关系

若邻接顶点u和v的次序无所谓,则(u, v)为无向边,所有边均为无方向的图,即无向图,反之,有向图中均为有向边

路径pi=<v0,v1,v2,v3,v4...vk>  长度|pi|=k

简单路径,图中不含重复节点的路径,起点等于终点的路径为环路

有向无环图

欧拉环路,哈密尔顿环路

2.图的表示和实现

邻接矩阵:顶点与顶点之间构成的矩阵,由于具有对称性,邻接矩阵的表示方法存在冗余

关联矩阵:顶点与边之间构成的矩阵

Vertex:包括data,入度,出度,在遍历树中的父节点,在遍历树中的优先级,顶点状态(UNDISCOVERED,DISCOVERED,VISITED)

Edge:数据,权重,类型

 

3.顶点静态操作

对于任意顶点i,如何枚举其所有第邻接顶点neighbor?

int nextNbr(int i,int j){
    while((-1<j) && !exists(i,--j));
    return j;
}
确定第一个有效的邻居
int firstNbr(int i){
return nextNbr(i,n);
}

4.边操作

判断边(i,j)是否存在
int exists(int i,int j){   return (0<=i) && (i<n) && (0 <= j) && (j < n) && E[i][j] != NULL;
}
边插入
void insert(Te const& edge, int w,int i,int j){
  if(exists(i,j)) return; //忽略已有的边
E[i][j] = new Edge<Te>(edge,w);
e++;
v[i].outDegree++; //更新i的初度
v[j].inDegree++; //更新j的入度
}

边删除
Te remove(int i, int j){
Te eBak = edge(i, j);
delete E[i][j];
E[i][j] = NULL;
e--;
v[i].outDegree--;
v[j].inDegree--;
return eBak;
}

邻接矩阵的空间利用率较低。

平面图:不相邻的面不相交

 

化繁为简(采用广度优先搜索,进行遍历搜索)

graph--->tree--->sequence

始自顶点s的广度优先搜索:

访问顶点s

依次访问s所有尚未访问的邻接顶点

依次访问它们尚未访问的邻接顶点

。。。

如此反复

直至没有尚未访问的邻接顶点

图的广度优先遍历,等于树的层次遍历

void BFS(int v, int & clock){
    Queue<int> Q;
    status(v)=DISCOVERED;
    Q.enqueue(v);
    while(!Q.empty()){
        int v=Q.dequeue();
        dTime(v) = ++clock;
        for(int u=firstNbr(v); -1<u; u=nextNbr(v, u)){
            if(UNDISCOVERED == status(u)){
status(u)=DISCOVERED;
Q.enqueue(u);
status(v,u)=TREE;
parent(u)=v;
}else
status(v,u)=CROSS } status(v)=VISITED; } }

 

posted on 2018-03-13 22:26  sonofthesea  阅读(103)  评论(0编辑  收藏  举报