图的遍历之BSF广度优先算法6.2.2(网络整理)
2017-04-20 08:16
417 查看
图的广度优先遍历和树的层序遍历相似,伪代码见下图:
(以上图片来自网络)
(以上图片来自网络)
#include<stdlib.h> #include<stdbool.h> #include<stdio.h> #define MaxVertexNum 100 /* 最大顶点数设为100 */ typedef int Vertex; /* 用顶点下标表示顶点,为整型 */ typedef int WeightType; /* 边的权值设为整型 */ typedef char DataType; /* 顶点存储的数据类型设为字符型 */ bool Visited[MaxVertexNum]; /*****/ typedef Vertex Ele; typedef struct QNode{ Ele data[MaxVertexNum]; int front,rear; }*Queue; Queue createQueue(){ Queue q=(Queue)malloc(sizeof(struct QNode)); q->front=q->rear=-1; return q; } bool isempty(Queue q){ return q->rear==q->front; } bool isfull(Queue q){ return (q->rear+1)%MaxVertexNum==q->front; } void add(Queue q,Ele e){ if(isfull(q)) {printf("Queue is full\n");return;} q->data[++q->rear]=e; } Ele del(Queue q){ if(isempty(q)) {printf("Queue is empty\n");return -1;} return q->data[++q->front]; } /***/ /* 边的定义 */ typedef struct ENode *PtrToENode; struct ENode{ Vertex V1, V2; /* 有向边<V1, V2> */ WeightType Weight; /* 权重 */ }; typedef PtrToENode Edge; /* 邻接点的定义 */ typedef struct AdjVNode *PtrToAdjVNode; struct AdjVNode{ Vertex AdjV; /* 邻接点下标 */ WeightType Weight; /* 边权重 */ PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */ }; /* 顶点表头结点的定义 */ typedef struct Vnode{ PtrToAdjVNode FirstEdge;/* 边表头指针 */ DataType Data; /* 存顶点的数据 */ /* 注意:很多情况下,顶点无数据,此时Data可以不用出现 */ } AdjList[MaxVertexNum]; /* AdjList是邻接表类型 */ /* 图结点的定义 */ typedef struct GNode *PtrToGNode; struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ AdjList G; /* 邻接表 */ }; typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */ LGraph CreateGraph( int VertexNum ) { Vertex V; /* 初始化一个有VertexNum个顶点但没有边的图 */ LGraph Graph=(LGraph)malloc(sizeof(struct GNode)); Graph->Nv=VertexNum; Graph->Ne=0; /* 初始化邻接表头指针 */ /* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */ for (V=0; V<Graph->Nv; V++) Graph->G[V].FirstEdge = NULL; return Graph; } void InsertEdge( LGraph Graph, Edge E ) { PtrToAdjVNode NewNode; /* 插入边 <V1, V2> */ /* 为V2建立新的邻接点 */ NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode->AdjV = E->V2; NewNode->Weight = E->Weight; /* 将V2插入V1的表头 */ NewNode->Next = Graph->G[E->V1].FirstEdge; Graph->G[E->V1].FirstEdge = NewNode; /* 若是无向图,还要插入边 <V2, V1> */ /* 为V1建立新的邻接点 */ NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode->AdjV = E->V1; NewNode->Weight = E->Weight; /* 将V1插入V2的表头 */ NewNode->Next = Graph->G[E->V2].FirstEdge; Graph->G[E->V2].FirstEdge = NewNode; } LGraph BuildGraph() { LGraph Graph; Edge E; Vertex V; int Nv, i; scanf("%d", &Nv); /* 读入顶点个数 */ Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */ scanf("%d", &(Graph->Ne)); /* 读入边数 */ if ( Graph->Ne != 0 ) { /* 如果有边 */ E = (Edge)malloc( sizeof(struct ENode) ); /* 建立边结点 */ /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */ for (i=0; i<Graph->Ne; i++) { scanf("%d %d %d", &E->V1, &E->V2, &E->Weight); /* 注意:如果权重不是整型,Weight的读入格式要改 */ InsertEdge( Graph, E ); } free(E); } /* 如果顶点有数据的话,读入数据 */ for (V=0; V<Graph->Nv; V++) scanf(" %c", &(Graph->G[V].Data)); return Graph; } /* 邻接表存储的图 - DFS */ void Visit( Vertex V ) { printf("正在访问顶点%d\n", V); } /* Visited[]为全局变量,已经初始化为false */ void BFS( LGraph Graph, Vertex V, void (*PVisit)(Vertex) ) { /* 以V为出发点对邻接表存储的图Graph进行BFS搜索 */ PtrToAdjVNode W; Queue q=createQueue(); (*PVisit)( V ); /* 访问第V个顶点 */ Visited[V] = true; /* 标记V已访问 */ add(q,V); while(!isempty(q)) { V=del(q); for(W=Graph->G[V].FirstEdge;W;W=W->Next) if ( !Visited[W->AdjV] ) /* 若W->AdjV未被访问 */ {(*PVisit)(W->AdjV);Visited[W->AdjV]=true;add(q,W->AdjV); } } } int main(){ for(int i=0;i<MaxVertexNum;i++) Visited[i]=false;//初始化为false LGraph Graph=BuildGraph(); BFS(Graph,0,Visit); return 0; }
#include<stdlib.h> #include<stdbool.h> #include<stdio.h> #define MaxVertexNum 100 /* 最大顶点数设为100 */ #define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/ typedef int Vertex; /* 用顶点下标表示顶点,为整型 */ typedef int WeightType; /* 边的权值设为整型 */ typedef char DataType; /* 顶点存储的数据类型设为字符型 */ /*****/ typedef Vertex Ele; typedef struct QNode{ Ele data[MaxVertexNum]; int front,rear; }*Queue; Queue createQueue(){ Queue q=(Queue)malloc(sizeof(struct QNode)); q->front=q->rear=-1; return q; } bool isempty(Queue q){ return q->rear==q->front; } bool isfull(Queue q){ return (q->rear+1)%MaxVertexNum==q->front; } void add(Queue q,Ele e){ if(isfull(q)) {printf("Queue is full\n");return;} q->data[++q->rear]=e; } Ele del(Queue q){ if(isempty(q)) {printf("Queue is empty\n");return -1;} return q->data[++q->front]; } /***/ bool Visited[MaxVertexNum]; /* 边的定义 */ typedef struct ENode *PtrToENode; struct ENode{ Vertex V1, V2; /* 有向边<V1, V2> */ WeightType Weight; /* 权重 */ }; typedef PtrToENode Edge; /* 图结点的定义 */ typedef struct GNode *PtrToGNode; struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */ DataType Data[MaxVertexNum]; /* 存顶点的数据 */ /* 注意:很多情况下,顶点无数据,此时Data[]可以不用出现 */ }; typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */ MGraph CreateGraph( int VertexNum ) { /* 初始化一个有VertexNum个顶点但没有边的图 */ Vertex V, W; MGraph Graph; Graph = (MGraph)malloc(sizeof(struct GNode)); /* 建立图 */ Graph->Nv = VertexNum; Graph->Ne = 0; /* 初始化邻接矩阵 */ /* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */ for (V=0; V<Graph->Nv; V++) for (W=0; W<Graph->Nv; W++) if(V==W) Graph->G[V][W]=0; else Graph->G[V][W] = INFINITY; return Graph; } void InsertEdge( MGraph Graph, Edge E ) { /* 插入边 <V1, V2> */ Graph-> 4000 G[E->V1][E->V2] = E->Weight; /* 若是无向图,还要插入边<V2, V1> */ Graph->G[E->V2][E->V1] = E->Weight; } MGraph BuildGraph() { MGraph Graph; Edge E; Vertex V; int Nv, i; scanf("%d", &Nv); /* 读入顶点个数 */ Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */ scanf("%d", &(Graph->Ne)); /* 读入边数 */ if ( Graph->Ne != 0 ) { /* 如果有边 */ E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */ /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */ for (i=0; i<Graph->Ne; i++) { scanf("%d %d %d", &E->V1, &E->V2, &E->Weight); /* 注意:如果权重不是整型,Weight的读入格式要改 */ InsertEdge( Graph, E ); } free(E); } /* 如果顶点有数据的话,读入数据 */ for (V=0; V<Graph->Nv; V++) scanf(" %c", &(Graph->Data[V])); return Graph; } void Visit( Vertex V ) { printf("正在访问顶点%d\n", V); } /* Visited[]为全局变量,已经初始化为false */ void BFS( MGraph Graph, Vertex V, void (*PVisit)(Vertex) ){ Queue q=createQueue(); /* 以V为出发点对邻接表存储的图Graph进行BFS搜索 */ (*PVisit)( V ); /* 访问第V个顶点 */ Visited[V] = true; /* 标记V已访问 */ add(q,V); while(!isempty(q)){ V=del(q); for(Vertex W=0;W<Graph->Nv;W++){ if(W!=V&&Graph->G[V][W]!=INFINITY&&!Visited[W])/* 若W是V的邻接点并且未访问过 */ {(*PVisit)( W); /* 访问第W个顶点 */ Visited[W] = true; /* 标记W已访问 */ add(q,W); } } } } int main(){ for(int i=0;i<MaxVertexNum;i++) Visited[i]=false;//初始化为false MGraph Graph=BuildGraph(); BFS(Graph,0,Visit); return 0; }
相关文章推荐
- 图的遍历之DSF深度优先算法6.2.1(网络整理)
- 无向连通图的广度优先遍历算法
- 【算法学习】图相关算法编程实现-深度优先遍历和广度优先遍历
- 最简洁的广度优先遍历算法模板
- 二叉树的深度优先,广度优先,以及层次遍历算法
- 简要说明树的深度优先、广度优先遍历算法,及非递归实现的特点
- 简要说明树的深度优先、广度优先遍历算法,及非递归实现的特点
- 笔试算法题(10):深度优先,广度优先以及层序遍历 & 第一个仅出现一次的字符
- 数据结构 基于队列的广度优先遍历算法判断完全二叉树
- 图的广度优先遍历算法运用队列主针对邻接表有向图
- (百度笔试)简要说明树的深度优先、广度优先遍历算法,及非递归实现的特点
- 算法:图的广度优先遍历(Breadth First Search)
- (百度笔试)简要说明树的深度优先、广度优先遍历算法,及非递归实现的特点
- C++ Boost graph库 广度优先遍历算法示例
- 图的深度优先遍历和广度优先遍历算法
- 图算法:广度优先遍历
- 图遍历算法分析--深度优先、广度优先(1)
- 图 深度优先遍历 广度优先遍历 非递归遍历 图解算法过程
- 图 深度优先遍历 广度优先遍历 非递归遍历 图解算法过程
- 数据结构和算法之:图的深度优先和广度优先遍历及其Java实现