C语言实现基于邻接表的完全无向图生成,图的深度优先搜索与广度优先搜索

ALGraph* InitGraph(ALGraph* g, int number)创建了完全无向图

ALGraph* CreatTestGraph(ALGraph *g)创建了测试用有向图

ALGraph* InitGraph(ALGraph* g, int number) 实现了完全无向图的生成

BFS(ALGraph *g)与DFS(ALGraph *g)实现了图的广度与深度优先搜索

g是生产的完全无向图

g2是测试用的有向图,如下所示:

邻接表中: 1 ->2 ->4           2->3             3->6        4->3->5          5->7->8

6->NULL            7->6->9            8->NULL      9->NULL

可知:

BFS:        1 2 4 3 5 6 7 8 9
DFS:        1 2 3 6 4 5 7 9 8

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 30
typedef struct ArcNode    //边表
{
    int adjvex;
    struct ArcNode* next;
}ArcNode;


typedef struct VNode{        //点表
    int data;
    ArcNode * first;    
}VNode;

typedef struct ALGraph      //邻接表
{
    VNode* vertcies[MAXSIZE];
    int vexnum,arcnum;
}ALGraph;

typedef struct Queue          //队列及相关操作
{
    VNode *data[MAXSIZE];
    int rear,front;
}Queue;

Queue* initQueue(){
    Queue* p = (Queue *)malloc(sizeof(Queue));
    p->rear=p->front=0;
    return p;
}

int isQueueEmpty(Queue *p){
    if(p->rear==p->front){
        return 1;
    }
    return -1;
}

int enQueue(Queue *p,VNode *node){
    if((p->rear+1)%MAXSIZE==p->front){
        printf("full error,please enlarge Maxsize\n");
        return -1;
    }
    p->data[p->rear]=node;
    p->rear=(p->rear+1)%MAXSIZE;
    return 1;
}

VNode* deQueue(Queue *p){
    if(p->rear==p->front){
        printf("empty error\n");
        return NULL;
    }
    VNode *temp =p->data[p->front];
    p->front = (p->front+1)%MAXSIZE;
    return temp;

}


ALGraph* InitGraph(ALGraph* g, int number){     //生成有number个节点的完全无向图
    g = (ALGraph*)malloc(sizeof(ALGraph));
    VNode *tempV;
    g->vexnum=number,g->arcnum=number*(number-1)/2;     //统计结点数和边数
    for(int i=0;i<number;i++){                   //节点初始化
        tempV = (VNode *)malloc(sizeof(VNode));
        tempV->data=i+1;
        g->vertcies[i]=tempV;
    }
    int k;                                       //k统计连接的次数,总共连接number-1条边
    for(int i=0;i<number;i++){
        k=1;
        int now = (i+k)%(number);
        ArcNode *p=(ArcNode*)malloc(sizeof(ArcNode));
        p->adjvex =now,p->next=NULL;
        g->vertcies[i]->first=p;                //first初始化
        k++;
        while(k<number){
            ArcNode* tempA;
            tempA =(ArcNode*)malloc(sizeof(ArcNode));
            now = (i+k)%(number);
            tempA->adjvex=now;
            tempA->next=NULL;
            p->next = tempA;                    //边表连接
            p=tempA;              
            k++;
        }
    }
    return g;
}

void VisitingBFS(ALGraph* g,int *visit,int begin,Queue *p){     //BFS队列实现
    int num = g->vexnum;
    printf("%d ",g->vertcies[begin]->data);
    visit[begin]=1;
    enQueue(p,g->vertcies[begin]);
    VNode * tempV;
    ArcNode * tempA;
    while (isQueueEmpty(p)!=1)
    {
        tempV =deQueue(p);
        for(tempA=tempV->first;tempA!=NULL;tempA=tempA->next){
            if(visit[tempA->adjvex]==0){
                tempV = g->vertcies[tempA->adjvex];
                printf("%d ",tempV->data);
                visit[tempA->adjvex]=1;
                enQueue(p,tempV);
            }
        }
    }
    
}

void BFS(ALGraph *g){           //BFS
    printf("BFS:\n");
    int num = g->vexnum;
    int visit[num];
    memset(visit,0,sizeof(visit));  //全赋值0
    Queue *p= initQueue();
    for(int i=0;i<num;i++){
        if(visit[i]==0){
            VisitingBFS(g,visit,i,p);
        }
    }
    printf("\n");
}

void VisitingDFS(ALGraph* g,int *visit,int begin){      //DFS递归实现
    VNode * tempV = g->vertcies[begin];
    ArcNode * tempA;
    visit[begin]=1;
    printf("%d ",tempV->data);
    if(tempV->first!=NULL){
        for(tempA=tempV->first;tempA!=NULL;tempA=tempA->next){
            if(visit[tempA->adjvex]==0){
                VisitingDFS(g,visit,tempA->adjvex);
            }
        }
    }

}



void DFS(ALGraph *g){             //DFS,为求简便此处采取递归实现
    printf("DFS:\n");
    int num = g->vexnum;
    int visit[num];
    memset(visit,0,sizeof(visit));
    for(int i=0;i<num;i++){
        if(visit[i]==0){
            VisitingDFS(g,visit,i);
        }
    }
    printf("\n");
}





void printALGRaph(ALGraph* g){                  //输出图的基本信息
    printf("num of vexnum is %d, num of arcnum is %d\n",g->vexnum,g->arcnum);
    int i=0;
    ArcNode *tempA;
    VNode * tempV;

    while (i<g->vexnum)
    {
        tempV = g->vertcies[i];
        printf("data is: %d \n",tempV->data);
        tempA =tempV->first;
        if (tempA!=NULL)
        {
            printf("%d -> %d ",i+1,tempA->adjvex+1);
            while(tempA->next!=NULL){
                printf("-> ");
                tempA=tempA->next;
                printf("%d ",tempA->adjvex+1);
            }
            printf("\n");
        }
        i++;
        
        
    }
    
}


ALGraph* CreatTestGraph(ALGraph *g){          //创建测试用有向图
    g = (ALGraph*)malloc(sizeof(ALGraph));
    g->vexnum=9,g->arcnum=10;
    VNode *tempV;
    ArcNode *tempA;
    for(int i=0;i<9;i++){                   //节点初始化
        tempV = (VNode *)malloc(sizeof(VNode));
        tempV->data=i+1;
        tempV->first=NULL;
        g->vertcies[i]=tempV;
    }
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=1,g->vertcies[0]->first=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=3,g->vertcies[0]->first->next=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=2,g->vertcies[1]->first=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=5,g->vertcies[2]->first=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=2,g->vertcies[3]->first=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=4,g->vertcies[3]->first->next=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=6,g->vertcies[4]->first=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=7,g->vertcies[4]->first->next=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=5,g->vertcies[6]->first=tempA;
    tempA = (ArcNode *)malloc(sizeof(ArcNode)),tempA->next=NULL;
    tempA->adjvex=8,g->vertcies[6]->first->next=tempA;
    return g;
}

int main(){
    ALGraph *g,*g1;
    g=InitGraph(g,5);
    printf("g:\n");
    printALGRaph(g);
    BFS(g);
    DFS(g);
    printf("\ng1:\n");
    g1 =CreatTestGraph(g1);
    printALGRaph(g1);
    BFS(g1);
    DFS(g1);
}

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来回答你的问题。 邻接表是一种表示数据结构,可以用来存储有向广度优先遍历是一种遍历的算法,可以按照层次顺序依次访问中的所有节点。 具体来说,基于邻接表存储有向广度优先遍历可以按照以下步骤进行: 1. 定义一个队列,用于存储待访问的节点。 2. 将起点节点入队。 3. 当队列不为空时,执行以下操作: - 取出队首节点,并将其标记为已访问。 - 遍历该节点的所有邻居节点,如果邻居节点未被访问过,则将其入队。 4. 重复步骤3,直至队列为空。 下面是基于邻接表存储有向广度优先遍历的C语言代码实现,假设邻接表存储在一个数组中,每个节点的邻居节点存储在一个链表中: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 100 // 邻接表节点的结构体 typedef struct ArcNode { int adjvex; // 邻接节点的编号 struct ArcNode *next; // 指向下一个邻接节点的指针 } ArcNode; // 顶点节点的结构体 typedef struct { int data; // 顶点的数据 ArcNode *firstarc; // 指向第一个邻接节点的指针 } VNode; // 邻接表的结构体 typedef struct { VNode vertices[MAX_VERTEX_NUM]; // 顶点数组 int vexnum; // 顶点数 int arcnum; // 边数 } ALGraph; // 初始化邻接表 void InitGraph(ALGraph *G) { int i; G->vexnum = 0; G->arcnum = 0; for (i = 0; i < MAX_VERTEX_NUM; i++) { G->vertices[i].data = 0; G->vertices[i].firstarc = NULL; } } // 添加边 void AddArc(ALGraph *G, int v, int w) { ArcNode *p; p = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = w; p->next = G->vertices[v].firstarc; G->vertices[v].firstarc = p; G->arcnum++; } // 广度优先遍历 void BFS(ALGraph *G, int v) { int visited[MAX_VERTEX_NUM] = {0}; // 标记数组,记录节点是否被访问过 int q[MAX_VERTEX_NUM]; // 队列 int front = 0, rear = 0; // 队头和队尾指针 int i, j; ArcNode *p; q[rear++] = v; // 将起点节点入队 visited[v] = 1; // 标记起点节点为已访问 while (front < rear) { i = q[front++]; // 取出队首节点 printf("%d ", i); // 访问该节点 p = G->vertices[i].firstarc; while (p != NULL) { j = p->adjvex; if (!visited[j]) { // 如果邻居节点未被访问过,则将其入队 q[rear++] = j; visited[j] = 1; } p = p->next; } } } int main() { ALGraph G; int n, m, i, v, w; printf("请输入顶点数和边数:\n"); scanf("%d%d", &n, &m); InitGraph(&G); G.vexnum = n; printf("请输入顶点的数据:\n"); for (i = 0; i < n; i++) { scanf("%d", &G.vertices[i].data); } printf("请输入每条边的起点和终点:\n"); for (i = 0; i < m; i++) { scanf("%d%d", &v, &w); AddArc(&G, v, w); } printf("广度优先遍历结果为:\n"); BFS(&G, 0); printf("\n"); return 0; } ``` 这段代码可以读入有向的顶点数和边数,然后按照邻接表的方式存储,并对起点节点进行广度优先遍历,输出访问的节点序列。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值