图的表示方法和C++实现
图的表示最长用的两种方法是:
1)、邻接矩阵表示法
2)、邻接表表示
下面是两种构造图的方法
1)邻接矩阵:
- #include <iostream>
- #include <vector>
- using namespace std;
- //枚举类型,图的种类 DG:有向图;WDG:带权值的有向图;
- //UDG: 无向图;WUDG: 带权值的无向图
- enum GraphKind {DG, WDG, UDG, WUDG};
- //vertexType顶点类型,VRType:顶点之间的关系类型,InfoType:弧的信息类型
- template <typename VertexType, typename VRType, typename InfoType>
- class MGraph
- {
- public:
- MGraph(int vexNum, GraphKind __kind) : vexnum(vexNum), arcnum(0), kind(__kind)
- {
- //分配顶点向量数组
- vvec = new VertexType[vexnum];
- //动态分配二维数组, 注意二维数组的动态分配
- arcs = new ArcCell *[vexnum];
- for (int i = 0; i < vexnum; i++)
- {
- //为每一行动态分配空间
- arcs[i] = new ArcCell[vexnum];
- }
- }
- void Create()
- {
- switch (kind)
- {
- case DG:
- {
- CreateDG(); //构造一个有向图
- break;
- }
- case WDG:
- {
- CreateWDG(); //构造一个带权有向图
- break;
- }
- case UDG:
- {
- CreateUDG(); //构造一个无向图
- break;
- }
- case WUDG:
- {
- CreateWUDG(); //构造一个带权无向图
- break;
- }
- default:
- return;
- }
- }
- //初始化顶点数组和邻接矩阵
- void Init()
- {
- cout << "请输入每个顶点的关键字:" << endl;
- VertexType val;
- for (int i = 0; i < vexnum; i++)
- {
- cin >> val;
- vvec[i] = val;
- }
- for (int i = 0; i < vexnum; i++)
- {
- ArcCell ac;
- ac.adj = 0;
- ac.info = NULL;
- for (int j = 0; j < vexnum; j++)
- {
- arcs[i][j] = ac;
- }
- }
- }
- //构造一个有向图
- void CreateDG()
- {
- Init();
- int vhead, vtail;
- cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
- while (cin >> vhead >> vtail)
- {
- arcnum++;
- arcs[vhead][vtail].adj = 1;
- }
- }
- //构造一个带权有向图
- void CreateWDG()
- {
- Init();
- int vhead, vtail;
- InfoType w;
- cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- arcnum++;
- arcs[vhead][vtail].adj = w;
- }
- }
- //构造一个无向图
- void CreateUDG()
- {
- Init();
- int vhead, vtail;
- cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
- while (cin >> vhead >> vtail)
- {
- arcnum += 2;
- arcs[vhead][vtail].adj = 1;
- arcs[vtail][vhead].adj = 1;
- }
- }
- //构造一个带权无向图
- void CreateWUDG()
- {
- Init();
- int vhead, vtail;
- InfoType w;
- cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- arcnum += 2;
- arcs[vhead][vtail].adj = w;
- arcs[vtail][vhead].adj = w;
- }
- }
- void displayGraph()
- {
- cout << "总共有" << vexnum << "个顶点,"
- << arcnum << "条边" << endl;
- for (int i = 0; i < vexnum; i++)
- {
- cout << "第" << i+1 << "个顶点是:" << vvec[i]
- << "相邻的边有: ";
- for (int j = 0; j < vexnum; j++)
- {
- if (arcs[i][j].adj != 0)
- cout << vvec[j] << "(" << arcs[i][j].adj << ") ";
- }
- cout << endl;
- }
- }
- private:
- struct ArcCell
- {
- VRType adj; //顶点关系类型。对于无权图,用1或0表示
- //表示相邻与否;对带权图,为权值类型
- InfoType info; //该弧相关的信息的指针
- };
- VertexType *vvec; //顶点向量
- ArcCell **arcs; //邻接矩阵
- int vexnum; //图的当前顶点个数
- int arcnum; //图的弧数
- GraphKind kind; //图的种类标志
- };
- int main()
- {
- cout << "构造无向图:" << endl;
- MGraph<char, int, int> udgGraph(8, UDG);
- udgGraph.Create();
- udgGraph.displayGraph();
- cout << "构造带权无向图:" << endl;
- MGraph<char, int, int> wudgGraph(9, WUDG);
- wudgGraph.Create();
- wudgGraph.displayGraph();
- cout << "构造有向图:" << endl;
- MGraph<char, int, int> dgGraph(6, DG);
- udgGraph.Create();
- udgGraph.displayGraph();
- cout << "构造带权有向图:" << endl;
- MGraph<char, int, int> wdgGraph(6, WDG);
- wdgGraph.Create();
- wdgGraph.displayGraph();
- system("pause");
- return 0;
- }
运行了一个带权有向图:
2)邻接链表
- #include <iostream>
- using namespace std;
- //枚举类型,图的种类 DG:有向图;WDG:带权值的有向图;
- //UDG: 无向图;WUDG: 带权值的无向图
- enum GraphKind {DG, WDG, UDG, WUDG};
- template<typename VertexType, typename InfoType>
- class ALGraph
- {
- public:
- ALGraph(int verNum, GraphKind _kind)
- : vexnum(verNum), arcnum(0), kind(_kind)
- {
- for (int i = 0; i < MAX_VERTEX_NUM; i++)
- vertices[i].firstarc = NULL;
- }
- //构造图,进行选择
- void Create()
- {
- switch (kind)
- {
- case DG:
- {
- CreateDG(); //构造一个有向图
- break;
- }
- case WDG:
- {
- CreateWDG(); //构造一个带权有向图
- break;
- }
- case UDG:
- {
- CreateUDG(); //构造一个无向图
- break;
- }
- case WUDG:
- {
- CreateWUDG(); //构造一个带权无向图
- break;
- }
- default:
- return;
- }
- }
- //打印邻接链表
- void displayGraph()
- {
- for (int i = 0; i < vexnum; i++)
- {
- cout << "第" << i+1 << "个顶点是:" << vertices[i].data
- << " 邻接表为: ";
- ArcNode *arcNode = vertices[i].firstarc;
- while (arcNode != NULL)
- {
- cout << " -> " << vertices[arcNode->adjvex].data
- << "(" << arcNode->info << ")";
- arcNode = arcNode->nextarc;
- }
- cout << endl;
- }
- }
- private:
- //初始化邻接链表的表头数组
- void InitVertics()
- {
- cout << "请输入每个顶点的关键字:" << endl;
- VertexType val;
- for (int i = 0; i < vexnum; i++)
- {
- cin >> val;
- vertices[i].data = val;
- }
- }
- //插入一个表结点
- void insertArc(int vHead, int vTail, InfoType w)
- {
- //构造一个表结点
- ArcNode *newArcNode = new ArcNode;
- newArcNode->adjvex = vTail;
- newArcNode->nextarc = NULL;
- newArcNode->info = w;
- //arcNode 是vertics[vHead]的邻接表
- ArcNode *arcNode = vertices[vHead].firstarc;
- if (arcNode == NULL)
- vertices[vHead].firstarc = newArcNode;
- else
- {
- while (arcNode->nextarc != NULL)
- {
- arcNode = arcNode->nextarc;
- }
- arcNode->nextarc = newArcNode;
- }
- arcnum++;
- }
- //构造一个有向图
- void CreateDG()
- {
- InitVertics();
- int vhead, vtail;
- cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
- while (cin >> vhead >> vtail)
- {
- insertArc(vhead, vtail, 0);
- }
- }
- //构造一个带权有向图
- void CreateWDG()
- {
- InitVertics();
- int vhead, vtail;
- InfoType w;
- cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- insertArc(vhead, vtail, w);
- }
- }
- //构造一个无向图
- void CreateUDG()
- {
- InitVertics();
- int vhead, vtail;
- cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
- while (cin >> vhead >> vtail)
- {
- insertArc(vhead, vtail, 0);
- insertArc(vtail, vhead, 0);
- }
- }
- //构造一个带权无向图
- void CreateWUDG()
- {
- InitVertics();
- int vhead, vtail;
- InfoType w;
- cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
- while (cin >> vhead >> vtail >> w)
- {
- insertArc(vhead, vtail, w);
- insertArc(vtail, vhead, w);
- }
- }
- //const数据成员必须在构造函数里初始化
- static const int MAX_VERTEX_NUM = 20; //最大顶点个数
- struct ArcNode //表结点
- {
- int adjvex; //该弧所指向的顶点的位置
- ArcNode *nextarc; //指向下一条弧的指针
- InfoType info; //该弧相关信息的指针
- };
- struct VNode //头结点
- {
- VertexType data; //顶点信息
- ArcNode *firstarc; //指向第一条依附于该顶点的弧的指针
- };
- /*VNode AdjList[MAX_VERTEX_NUM];*/
- /* AdjList[MAX_VERTEX_NUM] vertices;*/
- VNode vertices[MAX_VERTEX_NUM];
- int vexnum; //图的当前顶点数
- int arcnum; //图的弧数
- GraphKind kind; //图的种类
- };
- int main()
- {
- cout << "构造一个8个顶点的无向图:" << endl;
- ALGraph<char, int> udgGraph(8, UDG);
- udgGraph.Create();
- udgGraph.displayGraph();
- cout << "构造一个9个顶点的带权无向图:" << endl;
- ALGraph<char, int> wudgGraph(9, WUDG);
- wudgGraph.Create();
- wudgGraph.displayGraph();
- cout << "构造一个6个顶点的有向图:" << endl;
- ALGraph<char, int> dgGraph(6, DG);
- dgGraph.Create();
- dgGraph.displayGraph();
- cout << "构造一个9个顶点的带权有向图:" << endl;
- ALGraph<char, int> wdgGraph(9, WDG);
- wdgGraph.Create();
- wdgGraph.displayGraph();
- system("pause");
- return 0;
- }
图的表示方法和C++实现相关推荐
- 【高并发】又一个朋友面试栽在了Thread类的stop()方法和interrupt()方法上!
来自:冰河技术 写在前面 新一轮的面试已经过去,可能是疫情的原因吧,很多童鞋纷纷留言说今年的面试题难度又提高了,尤其是对并发编程的知识.我细想了下,也许有那么点疫情的原因吧,但无论面试的套路怎么变,只 ...
- Java并发编程—schedule方法和scheduleAtFixedRate方法的区别
原文作者:一叶丿清风 原文地址:schedule方法和scheduleAtFixedRate方法的区别 schedule方法和scheduleAtFixedRate方法都可以实现任务的延时和不延时执行 ...
- 基于水平集方法和G0模型的SAR图像分割
基于水平集方法和G0模型的SAR图像分割 Abstract(摘要) 这篇文章提出了一种分割SAR图像的方法,探索利用SAR数据中的统计特性将图像分区域.我们假设为SAR图像分割分配参数,并与水平集模型 ...
- 计算机管理创建新用户,win7系统添加新用户名的方法和win7系统计算机管理中没有本地用户和组的解决方法...
win7系统添加新用户名的方法 方法一:通过控制面板创建新的用户. 1.打开开始菜单,选择控制面板. 2.打开控制面板界面,选择用户账户. 3.进行用户设置界面,选择管理其它账户. 4.点击下面的创建 ...
- iOS-class方法和objc_getClass方法
根据上一篇博客iOS-class.object_getClass.objc_getClass.objc_getMetaClass区别的研究发现,发现主要还是class方法和objc_getClass方 ...
- 【视频】主成分分析PCA降维方法和R语言分析葡萄酒可视化实例|数据分享
最近我们被客户要求撰写关于主成分分析PCA的研究报告,包括一些图形和统计输出.降维技术之一是主成分分析 (PCA) 算法,该算法将可能相关变量的一组观察值转换为一组线性不相关变量.在本文中,我们将讨论 ...
- Node.js的环境搭建方法和 npm 的使用方法
Node.js的环境搭建方法和 npm 的使用方法 Node.js 环境的搭建 Node.js 介绍 Node.js 下载 配置Node.js node.js 测试 npm(包管理器)使用方法 npm ...
- 联想集群超算LICO初次使用踩坑说明(遇到的错误,一些使用方法和singularity新建容器方法)
联想集群超算LICO初次使用踩坑说明(遇到的错误,一些使用方法和singularity新建容器方法) 说明 本文主要写一些我这几天初次使用LICO的过程中遇到的一点问题和解决的办法,还有一些模块的规范 ...
- PIL库中Image类thumbnail方法和resize方法区别
from PIL import Image im=Image.open("C:\\Users\\kethur\\Desktop\\a.jpg") x,y=im.size pri ...
最新文章
- Vivado如何计算关键路径的建立时间裕量?(理论分析篇)
- tensorflow+python flask进行手写识别_使用tensorflow进行手写数字识别
- 企业级自动化运维神器Ansible
- iphone怎么查看wifi密码_WiFi密码忘了怎么办?一秒找回密码
- Google Maps 补丁绕过、得双倍奖金这么简单?我陷入了自我怀疑
- C++ 设计模式 —— 控制器设计模式(实现功能模块间通信)
- Asp.net 调用sqlserver存储过程参数传中文乱码!
- ORACLE11g数据库安装-刘建-专题视频课程
- 2022年个人如何申请微信H5支付接口?
- 2020年,拥抱不平凡
- ❤️UI自动化轻松解决微信手工群发消息的烦恼❤️
- c语言大作业之自动寄存柜,关于自动寄存柜的问题求解
- 【FTP】Entering Extended Passive Mode
- 《大明王朝》雪崩前,精英们的狂欢
- 阿里执行副主席蔡崇信投资NBA篮网队;工信部约谈运营商,不得限制用户资费选择丨价值早报
- [zz]Freeware, Open source and Commercial Website Security Tools and Services
- 为什么要使用flowable工作流
- android仿苹果悬浮窗,Android仿IOS悬浮拖动按钮
- 商城项目(四)整合SpringTask实现定时任务
- 【报告分享】DTC品牌私域用户运营手册-易观方舟(附下载)
热门文章
- JAVA入门级教学之(标识符与关键字)
- c 程序中的注释相当于空白字符_Python专题 | (三)注释、变量与输出
- 计算机二级必备快捷键知识,计算机二级考试中的一些注意事项️
- java面向对象多态特性
- Java的重载与覆盖,傻傻分不清!
- 干货丨总结5类面试官特点和应对方法
- python反序列化总结_单例模式的反序列化总结
- python第八周小测验_Python语言程序设计第2周测验+练习题复盘
- 劲乐团u显示服务器维护,劲乐团9YOU原版服务端架设教程
- android 分享到豆瓣,Android项目总结之社会化分享