图和BFS(广搜)

1.基本概念

图:vertex(顶点)集 和edge(边)集组成 通常表示为G = (V,E)
无向完全图:在无向图中,如果任意两个顶点之间都存在边,则称该图为 无向完全图。
有向完全图:在有向图中,如果任意两个顶点之间都存在方向相反的两条 弧,则称该图为有向完全图

2.图的基本操作

NewNode ( G ):建立一个新顶点,V=V∪{v}
DelNone ( G, v ):删除顶点v以及与之相关联的所有边
SetSucc ( G, v1, v2 ):增加一条边,E = E∪(v1,v2) ,V=V
DelSucc ( G, v1, v2 ):删除边(v1,v2),V不变
Succ ( G, v1, v2 ):求出v的所有直接后继结点
Pred ( G, v):求出v的所有直接前导结点
IsEdge ( G, v1, v2 ):判断(v1,v2)∈E
FirstAdjVex( G , v ): 顶点v 的第一个邻接顶点
NextAdjVex( G, v, w):顶点v 的某个邻接点w的下一个邻接顶点

3.图的存储结构

1.邻接矩阵:

用一个一维数组存储顶点信息!!!

用一个二维数组存储邻接信息

存储顶点和边的个数!!!(在Graph中)!!!

typedef struct { 
VertexData verlist [NumVertices];   //顶点表 
EdgeData edge[NumVertices][NumVertices]; //邻接矩阵—边表, 可视为边之间的关系 
int n, e;  //图的顶点数与边数 
} MTGraph;

存储结构的建立----算法实现的步骤:
1.确定图的顶点个数n和边数e;
2.输入顶点信息存储在一维数组vertex中;
3.初始化邻接矩阵;
4.依次输入每条边存储在邻接矩阵edge中;
4.1 输入边依附的两个顶点的序号i, j;
4.2 将邻接矩阵的第i行第j列的元素值置为1;
4.3 将邻接矩阵的第j行第i列的元素值置为1。

2.邻接表(对于有向图分为正邻接表和逆邻接表)

无向图的邻接表:
对于无向图的每个顶点vi,将所有与vi相邻的顶点链成一个单链表,称为顶点vi的边表(顶点vi的邻接表);

再把所有边表的指针和存储顶点信息的一维数组构成顶点表!!!邻接表除了每个顶点对应的边表之外还有一个定点表!!!

边表节点:

typedef struct node {//边表结点 
int adjvex;            //邻接点域(下标)
EdgeData cost; //边上的权值 
struct node *next; //下一边链接指针 
} EdgeNode;

顶点表节点:

typedef struct {              //顶点表结点 
VertexData  vertex; //顶点数据域 
EdgeNode * firstedge;//边链表头指针 
} VertexNode

图的邻接表:

typedef struct {         //图的邻接表 
VertexNode vexlist [NumVertices]; 
int n, e;                //顶点个数与边数 
} AdjGraph;

4.BFS 的基本概念

广度优先遍历----类似于树结构的层序遍历
设图G的初态是所有顶点都“未访问过(False)”,在G中任选 一个顶点 v 为源点,则广度优先搜索可定义为:
①首先访问出发点 v,并将其标记为“访问过 (True)”;
②接着依次访问所有与 v 相邻的顶点w1,w2…wt;
③然后依次访问与w1,w2… wt相邻的所有未访问的顶点;
④依次类推,直至图中所有与源点v有路相通的顶点都已访问过 为止;
⑤此时,从 v 开始的搜索结束,若G是连通的,则遍历完成;否 则在G中另选一个尚未访问的顶点作为新源点,继续上述搜 索过程,直到G中的所有顶点均已访问为止

5.从一个顶点出发BFS的步骤

1.初始化队列Q;
2. 访问顶点v; visited [v]=1; 顶点v入队Q;
3. 队列非空就让第一个元素出队并加入和该元素邻接的为访问过的顶点
4. 重复上述,直到所有顶点都已经被访问过

猜你喜欢

转载自blog.csdn.net/qq_41359808/article/details/88292985