图的遍历——广度优先遍历——邻接表

/*图的遍历——广度优先遍历——邻接表*/
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20
#define OK 1
#define ERROR 0
/*队列的存储结构*/
typedef int Status;
typedef int QElemtype;
typedef struct
{
    QElemtype data[MAXSIZE];
    int front;
    int rear;
}sqQueue;

/*邻接表的存储结构*/
#define MAXVEX 100      /*最大顶点数*/
typedef char VertexType;     /*顶点*/
typedef int EdgeType;   /*权值*/
typedef int Boolean;    /*Boolean是布尔类型,其值为TURE和FALSE*/
Boolean visited[MAXVEX];    /*访问标志的数组*/
typedef struct EdgeNode     /*边表结点*/
{
    int adjvex;     /*邻接点域,存储该顶点对应的下标*/
    EdgeType weight;    /*用于存储权值,对于非网图可以不需要*/
    struct EdgeNode * next;     /*链域,指向下一个邻接点*/
}EdgeNode;

typedef struct VertexNode   /*顶点表结点*/
{
    VertexType data;    /*顶点表结点*/
    EdgeNode * firstedge;   /*边表头指针*/
}VertexNode,AdjList[MAXVEX];

typedef struct 
{
    AdjList adjList;
    int numVertexes,numEdge;    /*图中当前顶点数和边数*/
}GraphAdjList;


Status InitQueue(sqQueue * Q)
{
    Q->front=0;
    Q->rear=0;
    return OK;
}


Status QueueLength(sqQueue Q)
{
    return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}

Status EnQueue(sqQueue * Q, QElemtype e)
{
    if((Q->rear+1)%MAXSIZE==Q->front)
    {
        return ERROR;
    }
    Q->data[Q->rear]=e;
    Q->rear=(Q->rear+1)%MAXSIZE;
    return OK;
}

Status DeQueue(sqQueue * Q,QElemtype * e)
{
    if(Q->front==Q->rear)
    {
        return ERROR;
    }
    *e=Q->data[Q->front];
    Q->front=(Q->front+1)%MAXSIZE;
    return OK;
}


/*邻接表的广度遍历算法*/
void BFSTraverse(GraphAdjList * GL)
{
    int i;
    EdgeNode * P;
    sqQueue Q;
    for(i=0;i<GL->numVertexes;i++)
        visited[i]=false;
    InitQueue(&Q);
    for(i=0;i<GL->numVertexes;i++)
    {
        if(!visited[i])
        {
            visited[i]=true;
            printf("%c",GL->adjList[i].data);
            EnQueue(&Q,i);
            while(QueueLength(Q)!=0)
            {
                DeQueue(&Q,&i);
                P=GL->adjList[i].firstedge;     /*找到当前顶点边表链表头指针*/
                while(P)
                {
                    if(!visited[P->adjvex]) /*若此顶点未被访问*/
                    {
                        visited[P->adjvex]=true;
                        printf("%c",GL->adjList[P->adjvex].data);
                        EnQueue(&Q,P->adjvex);  /*将此顶点入队列*/
                    }
                    P=P->next;  /*将指针指向下一个邻接点*/
                }
            }
        }
    }
}

int main()
{
    return 0;
}
基于邻接表广度优先遍历是一种遍历算法,它从的某个顶点开始遍历,先访问该顶点,然后依次访问该顶点的所有邻接点,再依次访问这些邻接点的邻接点,直到遍历完整个。下面是C语言实现基于邻接表广度优先遍历的代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 20 // 最大顶点数 // 邻接表结构体 typedef struct ArcNode { int adjvex; // 邻接点在顶点数组中的下标 struct ArcNode *nextarc; // 指向下一个邻接点的指针 } ArcNode; // 顶点结构体 typedef struct VNode { char data; // 顶点数据 ArcNode *firstarc; // 指向第一个邻接点的指针 } VNode, AdjList[MAX_VERTEX_NUM]; // 结构体 typedef struct { AdjList vertices; // 顶点数组 int vexnum, arcnum; // 顶点数和边数 } ALGraph; // 初始化邻接表 void InitGraph(ALGraph *G) { int i; G->vexnum = G->arcnum = 0; for (i = 0; i < MAX_VERTEX_NUM; i++) { G->vertices[i].firstarc = NULL; } } // 添加边 void AddArc(ALGraph *G, int v, int w) { ArcNode *p; p = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = w; p->nextarc = G->vertices[v].firstarc; G->vertices[v].firstarc = p; } // 广度优先遍历 void BFS(ALGraph *G, int v) { int visited[MAX_VERTEX_NUM] = {0}; // 标记数组,用于标记已访问的顶点 int queue[MAX_VERTEX_NUM], front = 0, rear = 0; // 队列,用于存储待访问的顶点 ArcNode *p; visited[v] = 1; // 标记起始顶点已访问 printf("%c ", G->vertices[v].data); // 访问起始顶点 queue[rear++] = v; // 将起始顶点入队 while (front != rear) { // 队列不为空时循环 v = queue[front++]; // 出队一个顶点 for (p = G->vertices[v].firstarc; p != NULL; p = p->nextarc) { // 遍历该顶点的所有邻接点 if (!visited[p->adjvex]) { // 如果该邻接点未被访问 visited[p->adjvex] = 1; // 标记该邻接点已访问 printf("%c ", G->vertices[p->adjvex].data); // 访问该邻接点 queue[rear++] = p->adjvex; // 将该邻接点入队 } } } } // 主函数 int main() { ALGraph G; int i, v, w; char data; InitGraph(&G); printf("请输入顶点数和边数:"); scanf("%d%d", &G.vexnum, &G.arcnum); printf("请输入顶点数据:"); for (i = 0; i < G.vexnum; i++) { scanf(" %c", &data); G.vertices[i].data = data; } printf("请输入边的顶点序号:"); for (i = 0; i < G.arcnum; i++) { scanf("%d%d", &v, &w); AddArc(&G, v, w); AddArc(&G, w, v); // 无向需要添加反向边 } printf("广度优先遍历结果:"); BFS(&G, 0); // 从第一个顶点开始遍历 printf("\n"); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值