邻接矩阵表示 深度遍历 广度遍历

简介: 邻接矩阵表示 深度遍历 广度遍历

邻接矩阵表示法是一种图的表示方法,其中每个顶点都有一个唯一的索引,而每条边则由两个顶点之间的连接确定。深度优先遍历(DFS)和广度优先遍历(BFS)是两种常用的图遍历算法。

1. 深度优先遍历(DFS):

深度优先遍历从根节点开始,沿着一条路径尽可能深入地访问节点,直到到达叶子节点。然后回溯到上一个节点,继续访问其他未访问过的节点。这个过程一直持续到所有节点都被访问过为止。

在邻接矩阵表示法中,可以使用递归或栈来实现深度优先遍历。以下是使用栈实现的示例代码:

#include <iostream>
#include <stack>
using namespace std;
void dfs(int matrix[][4], int start, bool visited[]) {
    stack<int> s;
    s.push(start);
    visited[start] = true;
    while (!s.empty()) {
        int node = s.top();
        s.pop();
        cout << node << " ";
        for (int i = 0; i < 4; i++) {
            if (matrix[node][i] == 1 && !visited[i]) {
                s.push(i);
                visited[i] = true;
            }
        }
    }
}
int main() {
    int matrix[4][4] = {
        {0, 1, 1, 0},
        {1, 0, 0, 1},
        {1, 0, 0, 1},
        {0, 1, 1, 0}
    };
    bool visited[4] = {false};
    dfs(matrix, 0, visited);
    return 0;
}

 

2. 广度优先遍历(BFS):

广度优先遍历从根节点开始,首先访问所有与根节点直接相连的节点,然后再访问这些节点的邻居节点,以此类推。这个过程一直持续到所有节点都被访问过为止。

在邻接矩阵表示法中,可以使用队列来实现广度优先遍历。以下是使用队列实现的示例代码:

#include <iostream>
#include <queue>
using namespace std;
void bfs(int matrix[][4], int start, bool visited[]) {
    queue<int> q;
    q.push(start);
    visited[start] = true;
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        cout << node << " ";
        for (int i = 0; i < 4; i++) {
            if (matrix[node][i] == 1 && !visited[i]) {
                q.push(i);
                visited[i] = true;
            }
        }
    }
}
int main() {
    int matrix[4][4] = {
        {0, 1, 1, 0},
        {1, 0, 0, 1},
        {1, 0, 0, 1},
        {0, 1, 1, 0}
    };
    bool visited[4] = {false};
    bfs(matrix, 0, visited);
    return 0;
}

 

3. 邻接矩阵表示 深度遍历 广度遍历

代码如下:

#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#define MaxInt  32767
#define MVNum 100
typedef char VerTexType;
typedef int ArcType;
//邻接矩阵
typedef  struct {
    VerTexType  vexs[MVNum];  /*存储顶点元素*/
    ArcType arcs[MVNum][MVNum];
    /*各顶点之间的关系或权值*/
    int  vexnum, arcnum; /*顶点数,边(或弧)的个数*/
}MGraph;
int visited[MVNum];
int visitedBFS[MVNum];
stack<VerTexType> mystack;
queue<VerTexType> myqueue;
//函数声明
void PrintVisited();
int LocateVex(MGraph& G, VerTexType v); //函数定义
void CreateMGraph(MGraph& G);
void DFS(MGraph& G, VerTexType v);
void BFS(MGraph& G, VerTexType v);
void TestDemoGraph();
//函数定义
void  CreateMGraph(MGraph& G) {
    int i = 0, j = 0, k = 0;
    cout << "输入顶点个数:";
    cin >> G.vexnum;
    cout << "输入边的个数:";
    cin >> G.arcnum;
    for (i = 0; i < G.vexnum; i++) {
        cout << "输入第" << i + 1 << "个顶点的名称:";
        cin >> G.vexs[i];
    }
    for (i = 0; i < G.vexnum; ++i)         //初始化邻接矩阵,
        for (j = 0; j < G.vexnum; ++j)
            G.arcs[i][j] = 0;
    cout << "输入边依附的顶点 ,如 a b " << endl;
    VerTexType v1, v2;
    for (k = 0; k < G.arcnum; ++k) {              //构造邻接矩阵
        cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
        cin >> v1 >> v2;                //输入一条边依附的顶点及权值
        i = LocateVex(G, v1);   //函数调用
        j = LocateVex(G, v2);   //确定v1和v2在G中的位置,即顶点数组的下标
        if (i == -1 || j == -1) {
            cout << "顶点名称错误" << endl;
            k--;
            continue;
        }
        G.arcs[i][j] = 1;               //边<v1, v2>的值为1
        G.arcs[j][i] = G.arcs[i][j];            //置<v1, v2>的对称边<v2, v1>的权值为w
    }//for
}
int LocateVex(MGraph& G, VerTexType v) { //函数定义
    //确定点v在G中的位置
    for (int i = 0; i < G.vexnum; ++i)
        if (G.vexs[i] == v)
            return i;
    return -1;
}//LocateVex
void PrintVexArc(MGraph& G) {
    int i = 0, j = 0;
    cout << "顶点列表:" << endl;
    for (i = 0; i < G.vexnum; i++) {
        cout << "\t" << G.vexs[i];
    }
    cout << endl << "邻接矩阵:" << endl;
    for (i = 0; i < G.vexnum; i++) {
        for (j = 0; j < G.vexnum; j++) {
            cout << "\t" << G.arcs[i][j];
        }
        cout << endl;
    }
}
void PrintVisited() {
    for (int i = 0; i < 6; i++) cout << visited[i] << "\t"; cout << endl;
}
void PrintVisitedBFS() {
    for (int i = 0; i < 6; i++) cout << visitedBFS[i] << "\t"; cout << endl;
}
void DFS(MGraph& G, VerTexType v) {  //从v点开始深度遍历
    int index = LocateVex(G, v);
    if (index == -1) {
        cout << "没有这个结点" << v << endl;
        return;
    }
    if (visited[index] == 1) {  //已经访问过了,就返回。
        return;
    }
    //没有访问过,直接标记访问,操作,没有访问过的邻接点入栈
    visited[index] = 1; //标记当前结点已经访问过了
    cout << v << "\t"; //访问当前结点V,对该结点进行操作,直接输出。
    PrintVisited();
    int j = 0;
    for (j = G.vexnum; j >= 0; j--) {
        if (G.arcs[index][j] == 1 && visited[j] == 0) {
            mystack.push(G.vexs[j]);
        }
    }
    while (!mystack.empty()) {
        VerTexType vex = mystack.top();
        mystack.pop();
        DFS(G, vex);
    }
}
void BFS(MGraph& G, VerTexType v) {   //从v点开始广度遍历
    int index = LocateVex(G, v);
    if (index == -1) {
        cout << "没有这个结点" << v << endl;
        return;
    }
    if (visitedBFS[index] == 1) {
        return;
    }
    //没有被访问过,
    visitedBFS[index] = 1;
    cout << v << "\t";
    PrintVisitedBFS();
    for (int i = 0; i < G.vexnum; i++) {
        if (G.arcs[index][i] == 1 && visitedBFS[i] == 0) {
            //  cout<<"["<<index<<"]["<<i<<"]="<<G.vexs[i]<<endl;
            myqueue.push(G.vexs[i]);
        }
    }
    while (!myqueue.empty()) {
        VerTexType vex = myqueue.front();
        myqueue.pop();
        //cout<<"pop-->"<<vex<<endl;
        BFS(G, vex);
    }
}
void TestDemoGraph() {
    MGraph G;
    CreateMGraph(G);
    PrintVexArc(G);
    cout << "DFS--->" << endl;
    DFS(G, 'b');
    cout << "BFS--->" << endl;
    BFS(G, 'b');
}
int main()
{
    TestDemoGraph();
    return 0;
}
/*
6
8
a
b
c
d
e
f
ab
af
ae
bc
bd
fd
ed
cd
*/

 

运行结果:

加油各位!!

目录
相关文章
|
前端开发 API 对象存储
FileSaver.js源码学习,纯前端实现文件下载
FileSaver.js源码学习,纯前端实现文件下载
1343 0
|
存储 分布式计算 大数据
hadoop和spark的区别
学习hadoop已经有很长一段时间了,好像是二三月份的时候朋友给了一个国产Hadoop发行版下载地址,因为还是在学习阶段就下载了一个三节点的学习版玩一下。在研究、学习hadoop的朋友可以去找一下看看
4690 0
|
7月前
|
开发者 Windows
NDM多线程下载器!实用的下载器,绿色版下载及安装教程
NDM是一款小巧高效的多线程下载器,支持Windows、Mac及浏览器插件,绿色单文件仅904KB,无需安装。已汉化,操作简单,下载速度快,支持HTTP/HTTPS/FTP协议,不支持磁力链接。使用前需关闭杀毒软件,配合7-ZIP解压,浏览器插件可自动嗅探音视频资源。
2373 2
|
4月前
|
JavaScript Java 关系型数据库
2026版基于springboot的大学生社团管理系统
本文探讨高校学生社团管理系统的研发背景与意义,分析当前国内研究现状,提出基于Spring Boot、Vue.js、MySQL及B/S架构的技术方案,旨在提升社团管理的信息化、智能化水平,推动校园文化可持续发展。
|
数据采集 机器学习/深度学习 存储
《构建人工智能新质生产力创新生态:路径与策略》
在科技飞速发展的时代,人工智能成为提升国家竞争力和推动经济高质量发展的关键力量。构建其创新生态需从五方面入手:强化技术研发创新,加大科研投入、建设创新平台、鼓励自主创新;完善数据要素体系,提升数据质量、打破数据孤岛、保障数据安全;加强人才队伍建设,优化高校培养体系、开展职业培训、引进高端人才;推动产业协同发展,培育龙头企业、促进产业集群发展、加强产业联盟建设;优化政策法规环境,完善政策支持体系、加快立法进程、加强伦理监管。这是一项系统工程,需要各方共同努力,为经济社会发展注入新动力。
415 4
|
Web App开发
让Chrome支持小于12px 的文字方式有哪些?区别?
让Chrome支持小于12px 的文字方式有哪些?区别?
324 0
|
数据采集 XML 机器学习/深度学习
5.3 目标检测YOLOv3实战:叶病虫害检测
这篇文章介绍了使用YOLOv3模型进行叶病虫害检测的实战过程,包括数据预处理、模型构建、训练和评估等关键步骤。
|
Python
python字符串的拼接和拆分,看这一篇就够了
python字符串的拼接和拆分,看这一篇就够了
569 0
|
机器学习/深度学习 算法 Python
python与朴素贝叶斯算法(附示例和代码)
朴素贝叶斯算法以其高效性和优良的分类性能,成为文本处理领域一项受欢迎的方法。提供的代码示例证明了其在Python语言中的易用性和实用性。尽管算法假设了特征之间的独立性,但在实际应用中,它仍然能够提供强大的分类能力。通过调整参数和优化模型,你可以进一步提升朴素贝叶斯分类器的性能。
602 0
|
数据处理 Python
Python中字符串、列表、字典常用的拼接方法有哪些?
Python中字符串、列表、字典常用的拼接方法有哪些?
362 1