邻接矩阵DFS,BFS代码实现

// 邻接矩阵的深度和广度优先遍历
#include <stdio.h>

#define OK 1      // 执行成功
#define ERROR 0   // 执行失败
#define TRUE 1    // 返回值为真
#define FALSE 0   // 返回值为假

typedef int Status; // 执行状态(OK、ERROR)
typedef int Boolean; // 布尔值(TRUE、FALSE)

typedef char VertexType; // 顶点元素类型
typedef int EdgeType; // 边上权值的类型

#define MAXSIZE 9 // 队列储存空间初始分配量
#define MAXVEX 100 // 最大顶点数

// 邻接矩阵结构(无向图)
typedef struct {
    VertexType vexs[MAXVEX]; // 顶点表
    EdgeType arc[MAXVEX][MAXVEX]; // 边表
    int numNodes, numEdges; // 图的顶点数、边数
} MGraph;

/************** 用到的队列结构与函数 **************/

// 循环队列顺序存储结构
typedef struct {
    int data[MAXSIZE]; // 用于存值的数组
    int front; // 头指针
    int rear; // 尾指针,若队列不空,指向队尾元素的下一个位置
} Queue;

/**
 * 初始化一个空队列
 * @param Q 队列
 * @return 执行状态
 */
Status InitQueue(Queue* Q) {
    Q->front = Q->rear = 0; // 队头和队尾指针都指向0
    return OK;
}

/**
 * 判断队列是否为空
 * @param Q 队列
 * @return 队列是否为空
 */
Boolean QueueEmpty(Queue Q) {
    if (Q.front == Q.rear) { // 队头等于队尾指针,队列为空
        return TRUE;
    }
    else {
        return FALSE;
    }
}

/**
 * 将元素e插入队列Q的队尾
 * @param Q 队列
 * @param e 插入的元素
 * @return 执行状态
 */
Status EnQueue(Queue* Q, int e) {
    // 队列已满,插入失败
    if ((Q->rear + 1) % MAXSIZE == Q->front) {
        return ERROR;
    }

    // 将元素e插入队尾
    Q->data[Q->rear] = e;

    // 设置队尾指针指向下一个位置,若到最后则转向头部
    Q->rear = (Q->rear + 1) % MAXSIZE;
    return OK;
}

/**
 * 队头元素出队,用e返回其值
 * @param Q 队列
 * @param e 队头元素的值
 * @return 执行状态
 */
Status DeQueue(Queue* Q, int* e) {
    // 对头指针等于对尾指针,此时队列为空,出队失败
    if (Q->front == Q->rear) {
        return ERROR;
    }

    // 将队头元素的值赋给元素e
    *e = Q->data[Q->front];

    // 设置队头指针指向下一个位置,若到最后则转向头部
    Q->front = (Q->front + 1) % MAXSIZE;
    return OK;
}

/*************************************************/

/**
 * 生成邻接矩阵
 * @param G 邻接矩阵
 */
void CreateMGraph(MGraph* G) {
    int i, j; // 用于遍历元素

    G->numEdges = 15; // 设置有15条边
    G->numNodes = 6; // 设置有9个顶点

    // 读入顶点信息,建立顶点表
    G->vexs[0] = ‘A‘;
    G->vexs[1] = ‘B‘;
    G->vexs[2] = ‘C‘;
    G->vexs[3] = ‘D‘;
    G->vexs[4] = ‘E‘;
    G->vexs[5] = ‘F‘;

    // 初始化图的边
    for (i = 0; i < G->numNodes; i++) {
        for (j = 0; j < G->numNodes; j++) {
            G->arc[i][j] = 0; // 设置所有边的值都为0
        }
    }

    // 设置特定边(如果arc[i][j] = 1,代表顶点i到顶点j有边相连)
    G->arc[0][1] = 1;
    G->arc[0][2] = 1;
    G->arc[0][4] = 1;
    G->arc[1][0] = 1;
    G->arc[1][3] = 1;
    G->arc[1][4] = 1;
    G->arc[2][0] = 1;
    G->arc[2][4] = 1;
    G->arc[2][5] = 1;
    G->arc[3][1] = 1;
    G->arc[3][4] = 1;
    G->arc[3][5] = 1;
    G->arc[4][0] = 1;
    G->arc[4][1] = 1;
    G->arc[4][2] = 1;
    G->arc[4][3] = 1;
    G->arc[4][5] = 1;
    G->arc[5][2] = 1;
    G->arc[5][3] = 1;
    G->arc[5][4] = 1;

    // 设置对称边
    for (i = 0; i < G->numNodes; i++) {
        for (j = i; j < G->numNodes; j++) {
            G->arc[j][i] = G->arc[i][j];
        }
    }
}

// 访问标志的数组
Boolean visited[MAXVEX];

/**
 * 邻接矩阵的深度优先递归算法
 * @param G 邻接矩阵
 * @param i 顶点下标
 */
void DFS(MGraph G, int i) {
    int j; // 用于遍历元素

    visited[i] = TRUE; // 记录该下标的元素已被访问

    printf("%c ", G.vexs[i]); // 打印该位置的顶点值

    // 遍历图中的顶点
    for (j = 0; j < G.numNodes; j++) {
        // 顶点i到顶点j有边相连,并且顶点j未被访问过
        if (G.arc[i][j] == 1 && !visited[j]) {
            DFS(G, j); // 对顶点j进行访问
        }
    }
}

/**
 * 邻接矩阵的深度遍历
 * @param G 邻接矩阵
 */
void DFSTraverse(MGraph G) {
    int i; // 用于遍历元素

    // 初始化设置所有顶点都没被访问过
    for (i = 0; i < G.numNodes; i++) {
        visited[i] = FALSE;
    }

    // 遍历顶点i
    for (i = 0; i < G.numNodes; i++) {
        // 如果顶点i未被访问过
        if (!visited[i]) {
            DFS(G, i); // 访问顶点i
        }
    }
}

/**
 * 邻接矩阵的广度遍历算法
 * @param G 邻接矩阵
 */
void BFSTraverse(MGraph G) {
    int i, j; // 用于遍历元素
    Queue Q; // 队列

    // 初始设置图的所有顶点都没被访问过
    for (i = 0; i < G.numNodes; i++) {
        visited[i] = FALSE;
    }

    InitQueue(&Q); // 初始化队列

    // 对每一个顶点做循环
    for (i = 0; i < G.numNodes; i++) {
        if (!visited[i]) { // 该顶点未被访问过,进行处理
            visited[i] = TRUE; // 设置该顶点i已被访问

            printf("%c ", G.vexs[i]); // 打印该顶点i的值

            EnQueue(&Q, i); // 将该顶点i入队

            // 当队列非空时,进行循环
            while (!QueueEmpty(Q)) {
                DeQueue(&Q, &i); // 将队头元素出队,赋值给i

                // 遍历当前节点以外的节点j
                for (j = 0; j < G.numNodes; j++) {
                    // 若顶点j与当前节点存在边,并且未被访问过
                    if (G.arc[i][j] == 1 && !visited[j]) {
                        visited[j] = TRUE; // 设置顶点j已被访问
                        printf("%c ", G.vexs[j]); // 打印顶点j的值

                        EnQueue(&Q, j); // 将顶点j入队
                    }
                }
            }
        }
    }
}

int main() {
    MGraph G; // 邻接矩阵
    CreateMGraph(&G); // 创建邻接矩阵
    printf("深度遍历:");
    DFSTraverse(G); // 深度遍历邻接矩阵

    printf("\n广度遍历:");
    BFSTraverse(G); // 广度遍历邻接矩阵

    return 0;
}

原文地址:https://www.cnblogs.com/yangmenda/p/11721264.html

时间: 2024-11-08 20:23:56

邻接矩阵DFS,BFS代码实现的相关文章

DFS BFS代码

#define maxnum 30 #include<bits_stdc++.h> int visited[maxnum]={0}; using namespace std; typedef struct bian//边 { int mark;//标记是否搜索 int ivex,jvex;//两顶点位置 bian *ilink,*jlink;//指向两顶点的其他边 int info;//信息 } bian,*pbian; typedef struct dian//点 { char name;

Dearboy&#39;s Puzzle (poj 2308 搜索 dfs+bfs)

Language: Default Dearboy's Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1202   Accepted: 208 Description Dearboy is a game lover. Recently, he loves playing the game Lian Lian Kan. This game is played on a board with N*M grids

HDU 4771 Stealing Harry Potter&#39;s Precious dfs+bfs

Stealing Harry Potter's Precious Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and his owl. When Hogwarts school is in holiday, Harry Potter has to go back to uncle Vernon's home. But he can't bring his

Dfs/Bfs/记忆化搜索问题 | 问题集合

写在前面 动归和搜索似乎我打得特憋懒. 可能是因为搜索打的太少了??? 然后之前做过的一些题我就不再写了,比如填涂颜色/海战啥的? 然后每一题打两种解法(:Dfs/Bfs 前提是在题目里两种都能A P1596 湖计数 题目描述 Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <=

【dfs/bfs+set+快速幂】swjtuOJ 2094

[dfs/bfs+set+快速幂]swjtuOJ 2094 [注:交大的看到这篇文章要学会自己写,不要为了比赛而比赛!~] 题目大意 问题一:主人公去度假,问经过a^b天后是星期几(简单题) 问题二:一个天平,n个重物,每个物体的重量wi已知,问能称出的所有重量有多少种? 问题二要注意到天平两侧都可以放重物,每一个重物的权值都可以赋值为w,0,-w,相当于三分,我们知道二分可以用二进制位运算进行枚举,例如:枚举所有子集 int j,k,top=0; int t = 1 << n; for(in

POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

POJ 3083 -- Children of the Candy Corn(DFS+BFS) 题意: 给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走 1)先输出左转优先时,从S到E的步数 2)再输出右转优先时,从S到E的步数 3)最后输出S到E的最短步数 解题思路: 前两问DFS,转向只要控制一下旋转方向就可以 首先设置前进方向对应的数字 向上--N--0 向右--E--1 向下--S--2 向左--W--3 比如说右转优先,即为向右,向前,向左,向后,即逆时针方向for(int i

FZU1205/SDUT1157_小鼠迷宫问题(DFS+BFS)

解题报告 http://blog.csdn.net/juncoder/article/details/38146041 题目传送门 题意 求最短路和最短路的路数. 思路: BFS+DFS,先求出最短路.在DFS搜等于最短路的条数. 不加优化SDUTOJ过了,数据就是水. 确定了最短路的长度,加上奇偶剪枝FOJ也过了. #include <queue> #include <cmath> #include <cstdio> #include <cstring>

poj3083——dfs+bfs综合题

POJ 3083   dfs+bfs+模拟 Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10564   Accepted: 4539 Description The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through

POJ 3083:Children of the Candy Corn(DFS+BFS)

Children of the Candy Corn Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9311 Accepted: 4039 Description The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through the maze facing zombies, ch