数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

文章目录

  • 数据结构上机实验
    • 1.要求
    • 2.图的实现(以无向邻接表为例)
      • 2.1创建图
        • 2.1.1定义图的顶点、边及类定义
        • 2.1.2创建无向图和查找
        • 2.1.3插入边
        • 2.1.4打印函数
      • 2.2图的深度优先搜索(DFS)
      • 2.3图的广度优先搜索(BFS)
    • 3.全部源码
      • 测试:
      • Graph.h
      • test.cpp

数据结构上机实验

1.要求

  图采用邻接表存储结构,编程实现图的深度优先搜索和广度优先搜索算法。
            

2.图的实现(以无向邻接表为例)

2.1创建图

2.1.1定义图的顶点、边及类定义

  我们定义一个邻接表类(ALGraph)。这里实现一些基础的数据结构。要注意结构体的嵌套。

  Edge: 用于表示图中的边,包含两个顶点(tail和head)和一个权重cost。

  ArcNode: 用于表示图中的有向边,包含一个目标顶点adjvex、一个权重info和一个指向下一个有向边的指针nextarc。

  VNode: 用于表示图中的顶点,包含一个数据值data和一个指向第一条边的指针fistarc。

  AdjGraph: 用于表示整个图,包含一个顶点数组表vertices(最大顶点数为MAXVex)、顶点数vexnum、边数arcnum和图的类型kind。

#define MAXVex 20 //最大的顶点数	
#define VElemType inttypedef enum {DG,    //有向图UDG,   //无向图DN,    //有向网UDN    //无向网
}GraphKind;//定义边
typedef struct 
{VElemType tail;VElemType head;int cost;
}Edge;//定义边节点
typedef struct ArcNode 
{int adjvex;	 //终点在数组表中的下表int info;	 //权值ArcNode* nextarc; //下一个边的地址
}ArcNode;//定义表头节点
typedef struct
{VElemType data;	 ArcNode* fistarc; //储存第一条边的结点地址
}VNode;//定义邻接表
typedef struct
{VNode vertices[MAXVex]; //储存MAXVex个VNode的数组表int vexnum;    //顶点数int arcnum;    //边数GraphKind kind;
}AdjGraph;//定义邻接表类
class ALGraph
{
private:AdjGraph ag;
};

  

2.1.2创建无向图和查找

  CreateGraph函数:

  该函数首先使用输入参数n和m来初始化图的顶点数和边数。它通过循环读入每个顶点的数据,并初始化顶点数组表。每个顶点的数据值被初始化为输入的值,而第一条边的地址被初始化为NULL。 接着,它通过循环读入每条边的信息,并建立边集。对于每条边,它查找两个顶点的位置,然后创建一个新的ArcNode来存储这条边。如果图是无向的(kind == UDN),它还会创建另一个ArcNode来存储反向边。

  LocateVex函数:

  这个函数用于查找给定数据值在顶点数组表中的位置。 它遍历整个顶点数组表,如果找到匹配的数据值,就返回该位置的索引;否则,返回-1。

//创建无向图
void CreateGraph(int n, int m)
{ag.vexnum = n;  //ag有n个顶点ag.arcnum = m;  //ag有m个边ag.kind = UDN;int i, j, w, h, t;VElemType u, v;ArcNode* p;for (i = 0; i < n; i++)  //初始化顶点数组表{cin >> ag.vertices[i].data;ag.vertices[i].fistarc = NULL;}for (j = 0; j < m; j++) //建立边集{cin >> u >> v >> w;  //输入一条弧<u,v,w>h = LocateVex(u);t = LocateVex(v);p = new ArcNode;  //储存无向边p->adjvex = t;p->info = w;p->nextarc = ag.vertices[h].fistarc;if (ag.kind == UDN)  //储存无向边(v,u){ag.vertices[h].fistarc = p;p = new ArcNode;p->adjvex = h;p->info = w;p->nextarc = ag.vertices[t].fistarc;ag.vertices[t].fistarc = p;}}
}//查找顶点信息在数组中的下表
int LocateVex(VElemType u)
{for (int i = 0; i < ag.vexnum; i++){if (u == ag.vertices[i].data){return i;}}return -1;
}

  

2.1.3插入边

  InsertArcGraph:

  接受三个参数:顶点u、顶点v和边的权重info。代码实现了向图中插入新的边的功能。如果指定的两个顶点不存在,则会在顶点数组表中插入它们。 然后,创建两个新的ArcNode节点来代表双向边,并将它们插入到两个顶点的第一条边链表中。最后,更新图的状态信息(顶点数和边数)。

//插入边
void InsertArcGraph(VElemType u, VElemType v, int info)
{int h = LocateVex(u), t = LocateVex(v);ArcNode* p;if (h == -1)  //在顶点数组表中插入顶点u{ag.vertices[ag.vexnum].data = u;ag.vertices[ag.vexnum].fistarc = NULL;h = ag.vexnum;ag.vexnum++;}if (t == -1)  //在顶点数组表中插入顶点t{ag.vertices[ag.vexnum].data = v;ag.vertices[ag.vexnum].fistarc = NULL;t = ag.vexnum;ag.vexnum++;}p = new ArcNode;p->adjvex = t;p->info = info;p->nextarc = ag.vertices[h].fistarc;ag.vertices[h].fistarc = p;p = new ArcNode;p->adjvex = h;p->info = info;p->nextarc = ag.vertices[t].fistarc;ag.vertices[t].fistarc = p;ag.arcnum++;
}

  

2.1.4打印函数

  Print()

  这段代码是一个用于打印图的顶点和边信息的函数。 它遍历图的顶点数组表和邻接表,并打印每个顶点的索引、数据值和邻居信息。输出格式可以帮助理解图的结构和连接关系。

//打印函数
void Print()
{// 顶点for (size_t i = 0; i < ag.vexnum; ++i){cout << "[" << i << "]" << "->" << ag.vertices[i].data << endl;}cout << endl;for (size_t i = 0; i < ag.vexnum; ++i){cout << ag.vertices[i].data << "[" << i << "]->";ArcNode* cur = ag.vertices[i].fistarc;while (cur){cout << "[" << cur->adjvex << ":" << cur->info << "]->";cur = cur->nextarc;}cout << "NULL" << endl;}cout << endl;
}

  

2.2图的深度优先搜索(DFS)

  深度优先搜索(DFS)是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索图的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点

  实现图的深度优先搜索(DFS)的算法。我们使用递归即可,同时要使用数组vis来追踪哪些节点已经被访问过。

  在DFS函数中,我们应该使用节点的索引进行访问和标记,如果遇到了没有标记的点,就进行DFS操作,直到遍历完我们所有的图即可。
在这里插入图片描述

//深度优先搜索
int vis[MAXVex];
void DFS(VElemType v)
{ArcNode* p;int h = LocateVex(v);cout << v;vis[h] = 1;for (p = ag.vertices[h].fistarc; p; p = p->nextarc){if (vis[p->adjvex] == 0){DFS(ag.vertices[p->adjvex].data);}}
}
void DFSTraverse()
{int i;for (i = 0; i < ag.vexnum; i++){vis[i] = 0;}for (i = 0; i < ag.vexnum; i++){if (!vis[i]){DFS(ag.vertices[i].data);}}cout << endl;
}

  

2.3图的广度优先搜索(BFS)

  广度优先搜索(BFS)是一种用于图的遍历或搜索的算法。这种算法会尽可能广地搜索图的节点,从一个起始节点开始,探索邻近节点,然后再探索下一层级的节点。

  图的广度优先搜索(BFS)算法,我们可以利用队列来实现,它是在图中查找从给定源节点到所有其他节点的路径的算法。在的代码中,我们需要定义了一个数组visi来跟踪已经访问过的节点,然后使用队列lq来存储待访问的节点。

  在BFSTraverse函数中,我们先初始化visi数组,然后遍历所有的节点。如果一个节点尚未被访问,你就调用BFS函数进行访问。使用传递进来的节点数据来查找其在图中的索引,然后不断重复操作,知道队列中的数据为0。
在这里插入图片描述

//广度优先搜索
int visi[MAXVex];
void BFS(VElemType v)
{int h = LocateVex(v);ArcNode* p;queue<VElemType> lq;lq.push(h);visi[h] = 1;while (!lq.empty()){h=lq.front();lq.pop();cout << ag.vertices[h].data;for (p = ag.vertices[h].fistarc; p; p = p->nextarc){if (!visi[p->adjvex]){lq.push(p->adjvex);visi[p->adjvex] = 1;}}}
}
void BFSTraverse()
{int i;for (i = 0; i < ag.vexnum; i++){visi[i] = 0;}for (i = 0; i < ag.vexnum; i++){if (!visi[i]){BFS(ag.vertices[i].data);}}cout << endl;
}

            

3.全部源码

测试:

在这里插入图片描述

完全联通图示例:

在这里插入图片描述

有孤立点的示例:

在这里插入图片描述

  

Graph.h

#pragma once#include<queue>namespace link_table
{
#define MAXVex 20 //最大的顶点数	
#define VElemType inttypedef enum {DG,    //有向图UDG,   //无向图DN,    //有向网UDN    //无向网
}GraphKind;//定义边
typedef struct 
{VElemType tail;VElemType head;int cost;
}Edge;//定义边节点
typedef struct ArcNode 
{int adjvex;	 //终点在数组表中的下表int info;	 //权值ArcNode* nextarc; //下一个边的地址
}ArcNode;//定义表头节点
typedef struct
{VElemType data;	 ArcNode* fistarc; //储存第一条边的结点地址
}VNode;//定义邻接表
typedef struct
{VNode vertices[MAXVex]; //储存MAXVex个VNode的数组表int vexnum;    //顶点数int arcnum;    //边数GraphKind kind;
}AdjGraph;//定义邻接表类
class ALGraph
{
public://创建无向图void CreateGraph(int n, int m){ag.vexnum = n;  //ag有n个顶点ag.arcnum = m;  //ag有m个边ag.kind = UDN;int i, j, w, h, t;VElemType u, v;ArcNode* p;for (i = 0; i < n; i++)  //初始化顶点数组表{cin >> ag.vertices[i].data;ag.vertices[i].fistarc = NULL;}for (j = 0; j < m; j++) //建立边集{cin >> u >> v >> w;  //输入一条弧<u,v,w>h = LocateVex(u);t = LocateVex(v);p = new ArcNode;  //储存无向边p->adjvex = t;p->info = w;p->nextarc = ag.vertices[h].fistarc;if (ag.kind == UDN)  //储存无向边(v,u){ag.vertices[h].fistarc = p;p = new ArcNode;p->adjvex = h;p->info = w;p->nextarc = ag.vertices[t].fistarc;ag.vertices[t].fistarc = p;}}}//查找顶点信息在数组中的下表int LocateVex(VElemType u){for (int i = 0; i < ag.vexnum; i++){if (u == ag.vertices[i].data){return i;}}return -1;}//计算顶点的度数int Degree(VElemType u){int h = LocateVex(u);int count = 0;ArcNode* p = ag.vertices[h].fistarc;while (p){count++;p = p->nextarc;}return count;}//插入边void InsertArcGraph(VElemType u, VElemType v, int info){int h = LocateVex(u), t = LocateVex(v);ArcNode* p;if (h == -1)  //在顶点数组表中插入顶点u{ag.vertices[ag.vexnum].data = u;ag.vertices[ag.vexnum].fistarc = NULL;h = ag.vexnum;ag.vexnum++;}if (v == INT32_MAX) return;if (t == -1)  //在顶点数组表中插入顶点t{ag.vertices[ag.vexnum].data = v;ag.vertices[ag.vexnum].fistarc = NULL;t = ag.vexnum;ag.vexnum++;}p = new ArcNode;p->adjvex = t;p->info = info;p->nextarc = ag.vertices[h].fistarc;ag.vertices[h].fistarc = p;p = new ArcNode;p->adjvex = h;p->info = info;p->nextarc = ag.vertices[t].fistarc;ag.vertices[t].fistarc = p;ag.arcnum++;}//深度优先搜索int vis[MAXVex];void DFS(VElemType v){ArcNode* p;int h = LocateVex(v);cout << v;vis[h] = 1;for (p = ag.vertices[h].fistarc; p; p = p->nextarc){if (vis[p->adjvex] == 0){DFS(ag.vertices[p->adjvex].data);}}}void DFSTraverse(){int i;for (i = 0; i < ag.vexnum; i++){vis[i] = 0;}for (i = 0; i < ag.vexnum; i++){if (!vis[i]){DFS(ag.vertices[i].data);}}cout << endl;}//广度优先搜索int visi[MAXVex];void BFS(VElemType v){int h = LocateVex(v);ArcNode* p;queue<VElemType> lq;lq.push(h);visi[h] = 1;while (!lq.empty()){h=lq.front();lq.pop();cout << ag.vertices[h].data;for (p = ag.vertices[h].fistarc; p; p = p->nextarc){if (!visi[p->adjvex]){lq.push(p->adjvex);visi[p->adjvex] = 1;}}}}void BFSTraverse(){int i;for (i = 0; i < ag.vexnum; i++){visi[i] = 0;}for (i = 0; i < ag.vexnum; i++){if (!visi[i]){BFS(ag.vertices[i].data);}}cout << endl;}//打印函数void Print(){// 顶点for (size_t i = 0; i < ag.vexnum; ++i){cout << "[" << i << "]" << "->" << ag.vertices[i].data << endl;}cout << endl;for (size_t i = 0; i < ag.vexnum; ++i){cout << ag.vertices[i].data << "[" << i << "]->";ArcNode* cur = ag.vertices[i].fistarc;while (cur){cout << "[" << cur->adjvex << ":" << cur->info << "]->";cur = cur->nextarc;}cout << "NULL" << endl;}cout << endl;}private:AdjGraph ag;
};}

  

test.cpp

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;#include"Graph.h"void TestGraph1()
{link_table::ALGraph ag;ag.CreateGraph(0, 0);ag.InsertArcGraph(0, 1, 7);ag.InsertArcGraph(0, 2, 3);ag.InsertArcGraph(0, 3, 4);ag.InsertArcGraph(3, 4, 6);ag.InsertArcGraph(1, 2, 5);ag.InsertArcGraph(1, 3, 2);ag.InsertArcGraph(1, 4, 1);ag.InsertArcGraph(2, 4, 7);//创建孤立点,INT32_MAX代表没有连接任何边ag.InsertArcGraph(5, INT32_MAX, 0);cout << "该相邻表为:\n";ag.Print(); cout << "深度优先搜索的结果为:";ag.DFSTraverse();cout << "广度优先搜索的结果为:";ag.BFSTraverse();}int main()
{TestGraph1();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/142899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

竞赛 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

技术贴 | SQL 执行 - 执行器优化

本期技术贴主要介绍查询执行引擎的优化。查询执行引擎负责将 SQL 优化器生成的执行计划进行解释&#xff0c;通过任务调度执行从存储引擎里面把数据读取出来&#xff0c;计算出结果集&#xff0c;然后返回给客户。 在关系型数据库发展的早期&#xff0c;受制于计算机 IO 能力的…

前端JS解构数组对象

// 3. 对象数组解构const arr [{username: 小明,age: 18,agw:19},{username: 小ha,age: 18,agw:19}]arr.map(item>item.age)//js结构数组对象console.log( arr.map(item>{return {aaa:item.age,bbb:item.username}}))

搜维尔科技:【软件篇】TechViz是一款专为工程设计的专业级3D可视化软件

在沉浸式房间内深入研究您自己的 3D 数据 沉浸式房间是一个交互式虚拟现实空间&#xff0c;其中每个表面&#xff08;墙壁、地板和天花板&#xff09;都充当投影屏幕&#xff0c;创造高度沉浸式的体验。这就像您的 3D 模型有一个窗口&#xff0c;您可以在其中从不同角度走动、…

bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds: ceph-deploy mds

创建池 [rootceph-0 ~]# ceph osd pool create cephfs_data 64 pool cephfs_data created [rootceph-0 ~]# ceph osd pool create cephfs_metadata 32 pool cephfs_metadata created cephfs_metadata 64 报错 官方说明&#xff1a; 元数据池通常最多可容纳几 GB 的数据。为…

haproxy端口耗尽no free ports

用haproxy配置负载均衡时出现端口不足错误&#xff1b;后端服务连接一会高一会儿低&#xff0c;从0到1w、2w跳变&#xff1b;实际连接数为4w左右&#xff1b; haproxy[8765]: Connect() failed for backend 09e581: no free ports. 问题描述 在请求很少的时候&#xff0c;工作…

人工智能与大数据:驱动现代业务转型的双引擎

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和大数据已成为驱动业务和技术创新的关键力量。它们的结合不仅重塑了传统行业&#xff0c;也催生了新的商业模式和服务方式。 AI与大数据在零售行业的应用 在零售行业&#xff0c;AI和大数据的应用已经成为提…

排序 算法(第4版)

本博客参考算法&#xff08;第4版&#xff09;&#xff1a;算法&#xff08;第4版&#xff09; - LeetBook - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 本文用Java实现相关算法。 我们关注的主要对象是重新排列数组元素的算法&#xff0c;其中每个元素…

No208.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

echarts官网卡?

全网echarts案例资源大总结和echarts的高效使用技巧&#xff08;细节版&#xff09; - 掘金 drawnLine() {let myChart echarts.init(document.getElementById("grade"));// 绘制图表myChart.setOption({title: {left: "center",},tooltip: {trigger: &qu…

数字孪生智慧园区:大数据驱动下的运营管理革新

随着物联网、大数据、云计算等技术的飞速发展&#xff0c;数字孪生技术应运而生&#xff0c;它将物理世界与数字世界紧密连接起来&#xff0c;为各行各业提供了前所未有的解决方案。智慧园区作为城市的重要组成部分&#xff0c;通过数字孪生技术&#xff0c;可以实现更加高效、…

如何在 Windows 10/11 上高质量地将 WAV 转换为 MP3

WAV 几乎完全准确地存储了录音硬件所听到的内容&#xff0c;这使得它变得很大并占用了更多的存储空间。因此&#xff0c;WAV 格式在作为电子邮件附件发送、保存在便携式音频播放器上、通过蓝牙或互联网从一台设备传输到另一台设备等时可能无法正常工作。 如果您遇到 WAV 问题&…

数据库数据恢复—MSSQL报错“附加数据库错误823”如何恢复数据?

数据库故障&分析&#xff1a; MSSQL Server数据库比较常见的报错是“附加数据库错误823”。如果数据库有备份&#xff0c;只需要还原备份即可&#xff1b;如果无备份或者备份不可用&#xff0c;则需要使用专业的数据恢复手段去恢复数据。 MSSQL Server数据库出现“823”的报…

1.jvm基本知识

目录 概述jvm虚拟机三问jvm是什么&#xff1f;java 和 jvm 的关系 为什么学jvm怎么学习为什么jvm调优?什么时候jvm调优调优调什么 结束 概述 相关文章在此总结如下&#xff1a; 文章地址jvm类加载系统地址双亲委派模型与打破双亲委派地址运行时数据区地址运行时数据区-字符串…

理工ubuntu20.04电脑配置记录

8188gu无线网卡配置 首先下载github上的文件&#xff0c;进入文件夹 安装make命令 1. 查看usb无线网卡 sudo lsusb|grep 8188 2. 环境准备 sudo apt-get install git make build-essential git dkms linux-headers-$(uname -r) 3. 编译安装 git clone https://github.com…

敏感数据是什么?包含哪些?如何保障安全?

最近看到不少小伙伴在问&#xff0c;敏感数据是什么&#xff1f;包含哪些&#xff1f;如何保障安全&#xff1f;这里我们小编就给大家一一解答一下&#xff0c;仅供参考哦&#xff01; 敏感数据是什么&#xff1f; 敏感数据&#xff0c;是指泄漏后可能会给社会或个人带来严重危…

UE5、CesiumForUnreal实现加载GeoJson绘制墙体(Wall)功能(StaticMesh方式)

文章目录 1.实现目标2.实现过程2.1 实现原理2.2 具体代码2.3 应用测试2.3.1 流动材质2.3.2 蓝图测试3.参考资料1.实现目标 与上一篇以StaticMesh方式实现面类似,本文通过读取GeoJson数据,在UE中以StaticMeshComponent的形式绘制出墙体数据,并支持Editor和Runtime,在Editor下…

C#中.NET Framework 4.8控制台应用通过EF访问已建数据库

目录 一、创建.NET Framework 4.8控制台应用 二、建立数据库 1. 在SSMS中建立数据库Blogging 2.在VS上新建数据库连接 三、安装EF程序包 四、自动生成EF模型和上下文 1.Blog.cs类的模型 2.Post.cs类的模型 3.BloggingContext.cs数据库上下文 五、编写应用程序吧 我们…

流量分析(5.5信息安全铁人三项赛数据赛题解)

黑客通过外部的web服务器攻击到企业内部的系统中&#xff0c;并留下了web后门&#xff0c;通过外部服务器对内部进行了攻击。 目录 黑客攻击的第一个受害主机的网卡IP地址 黑客对URL的哪一个参数实施了SQL注入 第一个受害主机网站数据库的表前缀(加上下划线 例如abc_) 第一…

哔哩哔哩自动引流软件的运行分享,以及涉及到技术与核心代码分享

先来看实操成果&#xff0c;↑↑需要的同学可看我名字↖↖↖↖↖&#xff0c;或评论888无偿分享 大家好&#xff0c;我是一名专注于自动引流软件研发的技术专家。今天&#xff0c;我将与大家分享自动引流软件涉及到的技术与核心代码&#xff0c;希望能为大家提供一些有价值的参…