无向图 广度优先遍历 c语言实现

这里记录一下无向图的广度优先遍历,无向图用邻接表表示,使用的图的示例图如下,关于图的表示可以参照博客:无向图的表示:邻接矩阵和邻接表,这里不再赘述,无向图的表示的代码被封装到头文件queue.h 中。
另外还涉及到C语言的队列问题,可以参照博客:C 循环队列实现,同样不再赘述,循环队列实现的代码被封装到头文件graph_represent.h 中。

程序使用示例图:
示例图

实现要点:
每个定点有三个状态,-1,0,1,-1:表示未发现的节点;0:表示已经发现但是还没有处理的节点;1:表示已经处理的节点。在遍历过程中同样保存了“树边(tree edge)”,树边表示在遍历过程中经历过的点。
程序框架如下:
这里写图片描述

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
#include "graph_represent.h"

void BFS(struct vNode** adj,int n,int s,int* parent){
    int* color = (int*)malloc(sizeof(int)*(n)); //-1:未发现,0:已发现,未处理, 1:已经处理
    int i;
    Queue* pending = createQue(n);  //创建队列

    for(i=0;i<n;i++){
        color[i] = -1;  //所有节点处于“未发现”状态
    }

    parent[s] = -1;
    color[s] = 0;
    add(pending,s);     //入队操作

    while(!isEmpty(pending)){
        int v = poll(pending);

        struct vNode* w = adj[v];
        while(w != NULL){
            if(color[w->value]==-1){
                color[w->value] = 0;
                add(pending,w->value);
                parent[w->value] = v;/**在这里处理树边**/
            }
            w = w->next;
        }
        printf("%d ",v);/**在这里处理节点**/
        color[v] = 1;
    }
    printf("\n");
}


void main(){

    //获得默认图,一共有7个节点
    int n = 7;
    struct vNode** adjVertics = default_wraper();
    int* parent = (int*)malloc(sizeof(int)*n);

    printf("\nbreadth first search:\n");
    BFS(adjVertics,n,2,parent);//从第二个节点开始遍历
}

从第二个节点开始遍历,输出为:2 0 1 3 5 4 6

以下是无向图广度优先遍历的 C 语言实现: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTICES 100 typedef struct { int v; int w; } Edge; typedef struct { int n; Edge edges[MAX_VERTICES*MAX_VERTICES]; } Graph; void init_graph(Graph* g, int n) { int i; g->n = n; for (i = 0; i < n*n; i++) g->edges[i].v = -1; } void add_edge(Graph* g, int u, int v, int w) { int i; for (i = 0; i < g->n*g->n; i++) { if (g->edges[i].v < 0) { g->edges[i].v = u; g->edges[i].w = w; g->edges[i+1].v = v; g->edges[i+1].w = w; return; } } printf("Too many edges\n"); } int bfs(Graph* g, int start_vertex, int target_vertex) { int queue[MAX_VERTICES]; int visited[MAX_VERTICES] = { 0 }; int front = 0, rear = 0; int v, i; queue[rear++] = start_vertex; visited[start_vertex] = 1; while (front != rear) { v = queue[front++]; if (v == target_vertex) return 1; for (i = 0; i < g->n*g->n; i++) { if (g->edges[i].v == v && !visited[g->edges[i].w]) { queue[rear++] = g->edges[i].w; visited[g->edges[i].w] = 1; } } } return 0; } int main() { Graph g; int n = 5; init_graph(&g, n); add_edge(&g, 0, 1, 1); add_edge(&g, 0, 4, 1); add_edge(&g, 1, 2, 1); add_edge(&g, 1, 3, 1); add_edge(&g, 1, 4, 1); add_edge(&g, 2, 3, 1); add_edge(&g, 3, 4, 1); printf("%d\n", bfs(&g, 0, 3)); return 0; } ``` 以上代码实现了一个无向图广度优先遍历,其中 `Graph` 结构体用于存储图的信息,包括顶点数和边,`init_graph` 和 `add_edge` 分别用于初始化图和添加边。 `bfs` 函数实现广度优先遍历,其中使用队列来存储待访问的顶点,使用 `visited` 数组来记录已访问的顶点。在 `main` 函数中,我们创建了一个无向图,并使用 `bfs` 函数从顶点 `0` 开始遍历,查找是否存在到顶点 `3` 的路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值