BFS(邻接表表示)

纯C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define VERTEX_NUM 8

typedef enum {FALSE = 0, TRUE = 1}BOOL;

typedef struct ArcNode {
    int adjvex;
    struct ArcNode *nextarc;    // struct不能少
}ArcNode;

BOOL visited[VERTEX_NUM + 1];    // 访问标志数组(备忘表)

int FirstAdjVex(ArcNode *G[VERTEX_NUM + 1], int v)
{
    if (G[v] == NULL)            // v是孤立顶点
        return -1;
    return G[v]->adjvex;
}

int NextAdjVex(ArcNode *G[VERTEX_NUM + 1], int v, int w)
{
    ArcNode *p = NULL;
    for (p = G[v]; p != NULL; p = p->nextarc) {
        if (p->adjvex == w) {                // 找到w,将返回
            if (p->nextarc == NULL)            // w已是v的最后一个邻接点
                return -1;
            return p->nextarc->adjvex;
        }
    }
    printf("错误!没找到w\n");
    return -1;
}

typedef struct Queue {
    int arr[VERTEX_NUM + 5];
    int front;
    int tail;
}Queue;

void BFSTraverse(ArcNode *G[VERTEX_NUM + 1])
{
    // 按广度优先非递归遍历图G。使用辅助队列p和访问标志数组visited。
    int v;
    int w;
    int u;
    Queue Q;    // 队列长度为VERTEX_NUM,不会假溢出
    Q.front = 0;
    Q.tail = 0;
    for (v = 1; v <= VERTEX_NUM; ++v)
        visited[v] = FALSE;
    
    for (v = 1; v <= VERTEX_NUM; ++v) {
        if (!visited[v]) {                        // v尚未访问
            visited[v] = TRUE;
            printf("%d\n", v);
            Q.arr[Q.tail++] = v;                // v入队列
            while (Q.tail != Q.front) {
                u = Q.arr[Q.front++];            // 队头元素出队并置为u
                for (w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) {
                    if (!visited[w]) {            // u的尚未访问的邻接顶点w入队列Q
                        visited[w] = TRUE;
                        printf("%d\n", w);
                        Q.arr[Q.tail++] = w;    // w入队列
                    }
                }
            }
        }
    }
}

void CreatAdjListGraph(ArcNode *G[VERTEX_NUM + 1])
{
    int a;
    int b;
    ArcNode *p;
    while (scanf("%d %d", &a, &b), !(a == 0 && b == 0)) {    //以0 0作为输入结束
        p = (ArcNode *)malloc(sizeof(ArcNode));
        if (p == NULL) {
            printf("OVERFLOW!\n");
            exit(-1);
        }
        p->adjvex = b;
        p->nextarc = G[a];    // 头插入
        G[a] = p;
        
        p = (ArcNode *)malloc(sizeof(ArcNode));
        if (p == NULL) {
            printf("OVERFLOW!\n");
            exit(-1);
        }
        p->adjvex = a;
        p->nextarc = G[b];    // 头插入
        G[b] = p;
    }
}

void Display(ArcNode *G[VERTEX_NUM + 1])
{
    int i;
    ArcNode *p;
    for (i = 1; i <= VERTEX_NUM; i++) {
        printf("%d", i);
        for (p = G[i]; p != NULL; p = p->nextarc) {
            printf("->%d", p->adjvex);
        }
        printf("\n");
    }
}

void Free(ArcNode *G[VERTEX_NUM + 1])
{
    int i;
    ArcNode *p;
    ArcNode *q;
    for (i = 1; i <= VERTEX_NUM; i++) {
        for (p = G[i]; p != NULL;) {
            q = p;
            p = p->nextarc;
            free(q);
            q = NULL;
        }
    }
}

int main(int argc, char **argv)
{
    // 头结点数组设为指针数组
    ArcNode *G[VERTEX_NUM + 1] = {NULL};    // 若这句放到freopen下面则错误,C语言!
    freopen("cin.txt", "r", stdin);
    
    CreatAdjListGraph(G);    // 建图(邻接表表示)
    
    Display(G);                // 显示图
    
    BFSTraverse(G);         // 遍历图
    
    Free(G);                // 释放图
    
    return 0;
}

/* cin.txt:
1 2
2 4
2 5
8 4
8 5
1 3
3 6
3 7
6 7
0 0
*/

运行结果:

原文地址:https://www.cnblogs.com/jjtx/p/2551563.html