图的封装(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描述>这本书,对大学里学的数据结构做了一次复习(其实差不多忘干净了,哈哈).如果能将这些知识捡起来,融入到实际工作当中,估计编码水平将是一次质 ...
随机推荐
- 检查URL的可用性脚本
#!/bin/bash check_url() { HTTP_CODE=$(curl -o /dev/ -s -) ];then echo "Warning: $1 Access failu ...
- C和C++ 中的const
C++中的const正常情况下是看成编译期的常量,编译器并不为const分配空间,只是在编译的时候将期值保存在名字表中,并在适当的时候折合在代码中.所以,以下代码: #include <iost ...
- 使用CSS选择器定位页面元素
摘录:http://blog.csdn.net/defectfinder/article/details/51734690 CSS选择器也是一个非常好用的定位元素的方法,甚至比Xpath强大.在自动化 ...
- servlet在地址栏填写参数
单个参数:以"?"开头+参数名+"="符号+参数值 例如 https://i.cnblogs.com/EditPosts.aspx?opt=1 多个参数:以&q ...
- exec函数族
进程程序替换 进程程序替换原理 fork创建子进程执行的是和父进程相同的程序(也有可能是某个分支),通常fork出的子进程是为了完成父进程所分配的任务,所以子进程通常会调用一种exec函数(六种中的任 ...
- Spring Cloud、Spring Boot与Docker 学习资料汇总
使用Spring Cloud与Docker实战微服务https://gitee.com/itmuch/spring-cloud-bookhttps://eacdy.gitbooks.io/spring ...
- [转] 安装npm全局包提示权限不够
方法1 sudo npm i -g npm 方法2 修改usr/local的权限.使用sudo有一个风险是安装包可能会运行自己的一些脚本,使sudo操作变的不可控,不安全.可以通过将/usr/loca ...
- Hadoop Avro支持多输入AvroMultipleInputs
Avro 提供了1.x版本的AvroMultipleInputs,但是不支持2.x API版本,因此修改对应代码,增加对hadoop 2.x API版本的的支持 代码放在https://github. ...
- WinRAR 0day漏洞
WinRAR 0day漏洞(附利用过程) 英国安全机构Mohammad Reza Espargham的漏洞实验室发现,流行压缩工具WinRAR 5.21最新版里存在一个安全漏洞,目前该漏洞还属于零日漏 ...
- 卸载impala
1):删除impala rm -rf $(find / -name "*impala*") 2):卸载impala相关依赖 rm -rf $(find / -name " ...