依托图的邻接矩阵进行图的创建、深度优先遍历、广度优先遍历(C语言详解)

  1. 图:图G是一个有序二元组(V,E),其中V称为顶集(Vertices Set),E称为边集(Edges set),E与V不相交。它们亦可写成V(G)和E(G)。其中,顶集的元素被称为顶点(Vertex),边集的元素被称为边(edge)。图可分为有向图和无向图,这里以无向图为例。(图的定义
  2. 图的表示:邻接表和邻接矩阵,对于稀疏矩阵邻接表所占有的空间远小于邻接矩阵。(图的两种表示方法
  3. 深度优先:从给定点出发,按照某种搜索逻辑,一直往前走,直至进入死胡同。此时,将会回退到最近一个可通行的点,并从该点出发进行深度遍历,直至所有点均被访问。与广度优先相比,深度优先更有一条路走到黑的勇气。
  4. 广度优先:从给定点出发,按照某种搜索逻辑,依次访问距离最近的所有点。此时完成了第一次搜索,接下来以同样的方法进行下一次搜索,直至所有的点均被访问。与深度优先相比,广度优先显得更加的谨慎小心。
  5. 代码
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTICES 52
void initVisited();
int getPos(char x, int lenNow);
/*地图(二维表),取值为1表示两个点有关联*/
int graph[MAX_VERTICES][MAX_VERTICES];
/*顶点数*/
int vertices;
/*访问数组*/
int visited[MAX_VERTICES];
/*点集*/
char vertex[MAX_VERTICES];

/*创建地图*/
void creategraph()
{
    int i, j = 0, edges, x, y;
    printf("顶点数、边数:");
    scanf("%d %d", &vertices, &edges);
    /*接收多余的换行符,防止后面数据读取错误*/
    getchar();
    printf("%d对关联的点:\n", edges);
    for (i = 0;i < edges;i++)
    {
        char from, to;
        scanf("%c %c", &from, &to);
        getchar();
        /*获取该顶点在vertex的位置*/
        x = getPos(from, j);
        /*与vertex当前长度相等,说明该顶点不存在vertex中*/
        if (x == j)
        {
            vertex[j++] = from;
        }
        y = getPos(to, j);
        if (y == j)
        {
            vertex[j++] = to;
        }
        /*根据无向图的对称性,给关联两点对应的坐标赋值*/
        graph[x][y] = graph[y][x] = 1;
    }
}

/*获取指定顶点x在vertex中的位置,其中lenNow表示当前长度*/
int getPos(char x, int lenNow)
{
    int i = 0;
    for (;i < lenNow;i++)
    {
        if (vertex[i] == x)
        {
            return i;
        }
    }
    return i;
}

/*打印地图*/
void printgraph()
{
    int i, j;
    for (i = 0;i < vertices;i++)
    {
        for (j = 0;j < vertices;j++)
        {
            printf("%d ", graph[i][j]);
        }
        printf("\n");
    }
}

/*从下标为i的节点进行深度优先遍历*/
void DFS(int i)
{
    /*不能越界*/
    if (i >=0 && i < vertices)
    {
        /*输出节点,并置为已访问*/
        printf("%c ", vertex[i]);
        visited[i] = 1;
        int j = 0;
        /*对下标为i的这一行进行遍历*/
        for (;j < vertices;j++)
        {
            /*找到未被访问且对应坐标的值为1的列坐标,并对该列进行深度遍历*/
            if (visited[j] == 0 && graph[i][j] == 1)
            {
                DFS(j);
            }
        }
    }
}

/*从下标为i的节点进行广度优先遍历*/
void BFS(int i)
{
    if (i >=0 && i < vertices)
    {
        int queue[vertices], front = 0, rear = 0;
        /*将i入队*/
        queue[rear] = i;
        rear = (rear + 1) % vertices;
        while (front != rear)
        {
            /*出队,并置为已访问*/
            int j, pop = queue[front];
            front = (front + 1) % vertices;
            printf("%c ", vertex[pop]);
            visited[pop] = 1;
            /*遍历出队下标对应行*/
            for (j = 0;j < vertices;j++)
            {
                /*找到未被访问且对应坐标的值为1的列坐标,并进行入队*/
                if (visited[j] == 0 && graph[pop][j] == 1)
                {
                    queue[rear] = j;
                    rear = (rear + 1) % vertices;
                }
            }
        }
    }
}

void travel(int type)
{
    initVisited();
    int i;
    if (type == 0)
    {
        /*遍历每一个顶点*/
        for (i = 0;i < vertices;i++)
        {
            if (visited[i] == 0)
            {
                DFS(i);
            }
        }
    }
    else
    {
        for (i = 0;i < vertices;i++)
        {
            if (visited[i] == 0)
            {
                BFS(i);
            }
        }
    }
}

void initVisited()
{
    int i;
    for (i = 0;i < vertices;i++)
    {
        visited[i] = 0;
    }
}

int main()
{
    creategraph();
    printf("深度优先:");
    travel(0);
    printf("\n");
    printf("广度优先:");
    travel(1);
    return 0;
}


/*
测试数据
13 12
A K
K L
L M
A H
H I
I J
A E
E F
F G
A B
B C
C D
*/

6 截图
在这里插入图片描述
图片来源:百度图片–图的深度优先遍历
在这里插入图片描述

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用邻接矩阵实现深度优先遍历广度优先遍历C语言代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX_VERTEX_NUM 20 typedef char VertexType; typedef int EdgeType; typedef struct { VertexType vertex[MAX_VERTEX_NUM]; EdgeType edge[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; int vertex_num, edge_num; } MGraph; bool visited[MAX_VERTEX_NUM]; // 初始化邻接矩阵 void InitMGraph(MGraph *G) { int i, j; for (i = 0; i < G->vertex_num; i++) { for (j = 0; j < G->vertex_num; j++) { G->edge[i][j] = 0; } } } // 深度优先遍历 void DFS(MGraph *G, int v) { int i; visited[v] = true; printf("%c ", G->vertex[v]); for (i = 0; i < G->vertex_num; i++) { if (G->edge[v][i] && !visited[i]) { DFS(G, i); } } } // 广度优先遍历 void BFS(MGraph *G, int v) { int i, queue[MAX_VERTEX_NUM], front = 0, rear = 0; visited[v] = true; printf("%c ", G->vertex[v]); queue[rear++] = v; while (front != rear) { int w = queue[front++]; for (i = 0; i < G->vertex_num; i++) { if (G->edge[w][i] && !visited[i]) { visited[i] = true; printf("%c ", G->vertex[i]); queue[rear++] = i; } } } } int main() { MGraph G; int i, j, v; printf("请输入的顶点数和边数:"); scanf("%d%d", &G.vertex_num, &G.edge_num); printf("请输入的顶点信息:"); for (i = 0; i < G.vertex_num; i++) { scanf(" %c", &G.vertex[i]); } InitMGraph(&G); printf("请输入的边信息:\n"); for (i = 0; i < G.edge_num; i++) { printf("请输入第%d条边的起点和终点:", i + 1); scanf("%d%d", &v, &j); G.edge[v][j] = G.edge[j][v] = 1; } printf("深度优先遍历结果:"); for (i = 0; i < G.vertex_num; i++) { visited[i] = false; } for (i = 0; i < G.vertex_num; i++) { if (!visited[i]) { DFS(&G, i); } } printf("\n广度优先遍历结果:"); for (i = 0; i < G.vertex_num; i++) { visited[i] = false; } for (i = 0; i < G.vertex_num; i++) { if (!visited[i]) { BFS(&G, i); } } return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qian_Qian_IT

感谢您的赏识,我将持续创作~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值