图的封装(C++)
一. 问题说明
1.问题的简单描述
将图和网的的创建和基本操作分封装到class
用来熟悉此种数据结构和基于这种数据结构上的基本算法
采用VS2010编译环境
2.工作安排
二. 源代码
1.文件stdafx.h
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
/*
以下完成图的存储结构
(
关键在于结构体的组合
)
*/
#define INFINITY INT_MAX // 用整形最大值代替∞
const int MAX_VERTEX_NUM=;// 最大顶点个数
#define VRType int //顶点关系类型
#define InfoType string//弧相关信息
#define VertexType string//顶点类型
enum GraphKind{DG,DN,UDG,UDN};// 有向图,有向网,无向图,无向网
typedef struct
{
VRType adj; //adjacency 邻接
// 对图来说1(是),0(否)表示相邻关系
// 对网来说为权值
InfoType info; //Info 信息
//该弧相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//Arc 弧(边)
struct MGraph
{
VertexType vex[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix arcs; //邻接矩阵
int vexnum,arcnum ;
GraphKind kind; //图的种类
};
class Graph
{
private:
MGraph G;
public:
Graph();
void CreateUDG();//创建无向图
void CreateUDN();//创建无向网
void CreateDG(); //创建有向图
void CreateDN(); //创建有向网
void CreateUDG_BYFile();//创建无向图,通过文件
void CreateUDN_BYFile();//创建无向网,通过文件
void CreateDG_BYFile(); //创建有向图,通过文件
void CreateDN_BYFile(); //创建有向网,通过文件
int LocateVex(VertexType u); //以顶点名称确定其邻接矩阵中的位置
void Display();//展示图或网的顶点向量,和邻接矩阵
};
2.文件Graph_Matrix.cpp
#include "stdafx.h"
Graph::Graph()
{
cout<<"请输入图G的类型( 有向图:0; 有向网:1; 无向图 :2; 无向网 3;)"<<endl;
scanf("%d",&G.kind);
switch(G.kind)
{
case UDG: CreateUDG();
break;
case UDN: CreateUDN();
break;
case DG: CreateDG();
break;
case DN: CreateDN();
break;
}
}
void Graph::CreateUDG()
{
/*采用数组(邻接矩阵)表示法,构造无向图G
以边为输入单位,即输入边的俩个顶点
关键在于判断输入顶点是否存在,返回其位置
*/
int i,j,IncInfo;//是否包含边或弧的相关信息
VertexType va,vb;
cout<<"请输入无向图的顶点数,边数,变是否包含其他信息(是:1; 否;0;)"<<endl;
cin>>G.vexnum;//顶点数
cin>>G.arcnum;//边数
cin>>IncInfo;//是否具有相关信息的判断条件
cout<<"请输入"<<G.vexnum<<"个顶点的的值"<<endl;
for(i=; i<G.vexnum; i++)//构造顶点向量
{
cin>>G.vex[i];
}
for(i=; i<G.vexnum; i++)//初始化邻接矩阵
{
for(j=; j<G.vexnum; j++)
{
G.arcs[i][j].adj=;//图
G.arcs[i][j].info="NULL";//初始化为空串
}
}
cout<<"请输入"<<G.arcnum<<"条边的顶点1,顶点2:"<<endl;
for(int k=; k<G.arcnum; k++)//按边录入信息
{
cin>>va;
i=LocateVex(va);//查询下标,va所在的行坐标
cin>>vb;
j=LocateVex(vb);//查询下标,vb所在的行坐标
G.arcs[i][j].adj=; //表示va 与 vb 相连 无向图
G.arcs[j][i].adj=; //表示va与vb相连 无向图
if(IncInfo)
{
cout<<"请输入该边相关信息"<<endl;
cin>>G.arcs[i][j].info; //输入字符串
G.arcs[j][i].info=G.arcs[i][j].info;//对称阵
}
}
G.kind=UDG; //创建成功
}
void Graph::CreateUDN()
{
/*
原理和UDG相同,只是增加了权值的输入
*/
int i,j,IncInfo;//是否包含边或弧的相关信息
VertexType va,vb;
cout<<"请输入无向网的顶点数,边数,变是否包含其他信息(是:1; 否;0;)"<<endl;
cin>>G.vexnum;//顶点数
cin>>G.arcnum;//边数
cin>>IncInfo;//是否具有相关信息的判断条件
cout<<"请输入"<<G.vexnum<<"个顶点的的值"<<endl;
for(i=; i<G.vexnum; i++)//构造顶点向量
{
cin>>G.vex[i];
}
for(i=; i<G.vexnum; i++)//初始化邻接矩阵
{
for(j=; j<G.vexnum; j++)
{
G.arcs[i][j].adj=INFINITY;//网,无穷大表示不连接
G.arcs[i][j].info="NULL";//初始化为空串
}
}
for(int k=; k<G.arcnum; k++)//按边录入信息
{
cout<<"请输入第"<<k+<<"条边的顶点1,顶点2:"<<endl;
cin>>va;
i=LocateVex(va);//查询下标,va所在的行坐标
cin>>vb;
j=LocateVex(vb);//查询下标,vb所在的行坐标
cout<<"请输入权值"<<endl;
cin>>G.arcs[i][j].adj;
G.arcs[j][i].adj=G.arcs[i][j].adj;
if(IncInfo)
{
cout<<"请输入该边相关信息"<<endl;
cin>>G.arcs[i][j].info; //输入字符串
G.arcs[j][i].info=G.arcs[i][j].info;//对称阵
}
}
G.kind=UDN; //创建成功
}
void Graph::CreateDG()
{
/*
原理与UDG相同,邻接矩阵略有区别
*/
int i,j,IncInfo;//是否包含边或弧的相关信息
VertexType va,vb;
cout<<"请输入有向图的顶点数,边数,变是否包含其他信息(是:1; 否;0;)"<<endl;
cin>>G.vexnum;//顶点数
cin>>G.arcnum;//边数
cin>>IncInfo;//是否具有相关信息的判断条件
cout<<"请输入"<<G.vexnum<<"个顶点的的值"<<endl;
for(i=; i<G.vexnum; i++)//构造顶点向量
{
cin>>G.vex[i];
}
for(i=; i<G.vexnum; i++)//初始化邻接矩阵
{
for(j=; j<G.vexnum; j++)
{
G.arcs[i][j].adj=;//图
G.arcs[i][j].info="NULL";//初始化为空串
}
}
cout<<"请输入"<<G.arcnum<<"条弧的弧头,弧尾:"<<endl;
for(int k=; k<G.arcnum; k++)//按边录入信息
{
cin>>va;
i=LocateVex(va);//查询下标,va所在的行坐标
cin>>vb;
j=LocateVex(vb);//查询下标,vb所在的行坐标
G.arcs[j][i].adj=; //表示vb(弧尾) 与 vb(弧头) 相连,也就是说vb可以到达va,反之不一定 有向图 vb——>va
if(IncInfo)
{
cout<<"请输入该弧相关信息"<<endl;
cin>>G.arcs[i][j].info; //输入字符串
G.arcs[j][i].info=G.arcs[i][j].info;//对称阵
}
}
G.kind=DG; //创建成功
}
void Graph::CreateDN()
{
/*
原理和DG相同,只是增加了权值的输入
*/
int i,j,IncInfo;//是否包含边或弧的相关信息
VertexType va,vb;
cout<<"请输入有向网的顶点数,边数,变是否包含其他信息(是:1; 否;0;)"<<endl;
cin>>G.vexnum;//顶点数
cin>>G.arcnum;//边数
cin>>IncInfo;//是否具有相关信息的判断条件
cout<<"请输入"<<G.vexnum<<"个顶点的的值"<<endl;
for(i=; i<G.vexnum; i++)//构造顶点向量
{
cin>>G.vex[i];
}
for(i=; i<G.vexnum; i++)//初始化邻接矩阵
{
for(j=; j<G.vexnum; j++)
{
G.arcs[i][j].adj=INFINITY;//网,无穷大表示不连接
G.arcs[i][j].info="NULL";//初始化为空串
}
}
for(int k=; k<G.arcnum; k++)//按边录入信息
{
cout<<"请输入第"<<k+<<"条弧的弧头,弧尾:"<<endl;
cin>>va;
i=LocateVex(va);//查询下标,va所在的行坐标
cin>>vb;
j=LocateVex(vb);//查询下标,vb所在的行坐标
cout<<"请输入权值"<<endl;
cin>>G.arcs[j][i].adj;
if(IncInfo)
{
cout<<"请输入该弧相关信息"<<endl;
cin>>G.arcs[i][j].info; //输入字符串
G.arcs[j][i].info=G.arcs[i][j].info;//对称阵
}
}
G.kind=DN; //创建成功
}
int Graph::LocateVex(VertexType u)//给定顶点值,返回顶点在顶点数组中的下标,方便按边录入信息
{
for(int i=; i<G.vexnum; i++)
{
if(G.vex[i]==u)
{
return i;
}
}
return -;
}
void Graph::Display()
{
cout<<"顶点向量"<<endl;
for(int i=; i<G.vexnum; i++)
{
cout<<"顶点"<<G.vex[i]<<endl;
}
cout<<"邻接矩阵"<<endl;
for(int i=; i<G.vexnum; i++)
{
for(int j=;j<G.vexnum;j++)
{
cout<<G.arcs[i][j].adj<<"\t";
}
cout<<endl;
}
cout<<"顶点1 顶点2 信息"<<endl;
if(G.kind>) //对于无向图或者无向网来说,邻接矩阵是对称的
{
for(int i=; i<G.vexnum; i++)
{
for(int j=;j<i;j++)
{
if(G.arcs[i][j].adj!=&&G.arcs[i][j].adj!=INFINITY)
{
cout<<G.vex[i]<<"\t";
cout<<G.vex[j]<<"\t";
cout<<G.arcs[i][j].info<<endl;
}
}
}
}
else//对于有向图或者有向网来说,邻接矩阵必须要全部输出
{
for(int i=; i<G.vexnum; i++)
{
for(int j=;j<G.vexnum;j++)
{
if(G.arcs[i][j].adj!=&&G.arcs[i][j].adj!=INFINITY)
{
cout<<G.vex[i]<<"\t";
cout<<G.vex[j]<<"\t";
cout<<G.arcs[i][j].info<<endl;
}
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Graph g;
g.Display();
return ;
}
图的封装(C++)的更多相关文章
- 左右推拽显示对比图 - jQyery封装 - 附源文件
闲来无事,做了一个模块效果 左右拖拽显示对比图,是用jq封装的 利用鼠标距离左侧(0,0)坐标的横坐标位移来控制绝对定位的left值 再配合背景图fixed属性,来制作视觉差效果 代码如下 <! ...
- Echarts生成饼状图、条形图以及线形图 JS封装
1.在我们开发程序中,经常会用到生成一些报表,比方说饼状图,条形图,折线图等.不多说了,直接上封装好的代码,如下Echarts.js所示 以下代码是封装在Echarts.js文件中 /** * Cre ...
- JQ无缝轮播图-插件封装
类似京东的这种无缝轮播效果: 实例代码下载 HTML代码: <body> <!-- /*觅me 探索生活*/ --> <div class="test" ...
- echarts 拼图和折线图的封装 及常规处理
1.html <div id="wrap"></div> 2.js ; (function ($) { $.fn.extend({ echartsPie: ...
- springMvc-视图模型封装及注解参数
1.视图模型封装,ModelAndView可以向页面返回视图的同时吧模型也传入页面 2.注解参数,springMvc很好的地方在于简单,高效,@RequestParam注解能非常好的取得页面参数 代码 ...
- 一个手机图表(echarts)折线图的封装
//定义一组颜色值,按顺序取出 var colorGroup = ["#6ca3c4","#76bfa3","#ea8f7a"," ...
- 使用原生JS实现一个风箱式的demo,并封装了一个运动框架
声明,该DEMO依托于某个培训机构中,非常感谢这个培训结构.话不多说,现在开始改demo的制作. 首先,在前端的学习过程中,轮播图是我们一定要学习的,所以为了更加高效的实现各种轮播图,封装了一个运动的 ...
- android 项目学习随笔十七(ListView、GridView显示组图)
ListView.GridView显示组图,处理机制相同 <?xml version="1.0" encoding="utf-8"?> <Li ...
- JS高级-数据结构的封装
最近在看了<数据结构与算法JavaScript描述>这本书,对大学里学的数据结构做了一次复习(其实差不多忘干净了,哈哈).如果能将这些知识捡起来,融入到实际工作当中,估计编码水平将是一次质 ...
随机推荐
- ajax对象方法的使用
change.js文件的内容对象函数关键字:fnjQuery.fn.change = function () { this.css({"background": "red ...
- oracle 12c ORA-01017:invalid username/password; logon denied
Oracle 12C 中,想通过操作系统认证登录Oracle 数据库,有一些要注意的地方.不然就会遇到 ORA-01017:invalid username/password; logon denie ...
- HDU 1247 Hat’s Words(字典树活用)
Hat's Words Time Limit : 2000 / 1000 MS(Java / Others) Memory Limit : 65536 / 32768 K(Java / Othe ...
- webpack+vue打包之后输出配置文件修改接口文件
用vue-cli构建的项目通常是采用前后端分离的开发模式,也就是前端与后台完全分离,此时就需要将后台接口地址打包进项目中,but,难道我们只是改个接口地址也要重新打包吗?当然不行了,那就太麻烦了,怎么 ...
- DNS解析中的A记录、AAAA记录、CNAME记录、MX记录、NS记录、TXT记录、SRV记录、URL转发等
AA记录: 将域名指向一个IPv4地址(例如:100.100.100.100),需要增加A记录 NSNS记录: 域名解析服务器记录,如果要将子域名指定某个域名服务器来解析,需要设置NS记录 SOASO ...
- GO语言标准库—命令行参数解析FLAG
flag包是Go语言标准库提供用来解析命令行参数的包,使得开发命令行工具更为简单 常用方法 1.flag.Usage 输出使用方法,如linux下ls -h的帮助输出 2.flag.Type(参数名, ...
- element-ui上传文件带token
template> <el-upload action="test" :headers="myHeaders"></el-upload& ...
- js网页下载csv格式的表格
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- h5调用qq客户端
这是第一种: <a href="tencent://message/?uin=1014167202&Site=在线QQ&Menu=yes"> <i ...
- windows 设置开机启动,启动项
第一步ctrl+R输入以下任意一个 方法一: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 方法二: shell:start ...