文章目录
数据结构三级项目,有向有权图的应用。
整体架构
项目设计7个类(图一),另外还有一个基础的graph类,这些类中最主要的就是arrayWDgraph这个类了,其他的类都是为它服务的,关于图的功能和操作也都是在arrayWDgraph这个类里。arrayWDgraph继承了抽象类graph,并且实现了graph中的方法,同时做出了一定的扩展,编写了其他的方法。
类对应的实际问题
实际问题的描述
项目所对应的实际问题是军事信息整合与处理,具体到项目里就是对军事中地点占领,路线,队伍的安排。计划解决两个主要的问题,就是队伍的顺序安排以及地点间最短路径的计算。队伍顺序的安排就是对队伍上前线的顺序的安排,对于军队来说上战场时的队伍是有一定的顺序安排的,前面的队伍为后面的队伍做好铺垫,后面的队伍就可以迅速地投入战场,取得宝贵的时机。另一个就是对地点间的最短路径的计算,战场上需要在不同的地点作战,所以地点间的转移的路线一定要是最短的才可以,这样就可以迅速地抵达目的地。
实际问题在类中的体现
node类代表的是图中的点,edge类代表的是图中的边,vertexIterator类代表的是迭代器,work代表的是队伍,nodefrom是点的另一种表示,works代表的是队伍系统,graph是基类,而arrayWDgraph是继承基类的代表有向有权图的类。
(1)类的实现中,node类所带有的信息仅仅是点的编号和边的权值,这样一个点会存在边所对应的邻接数组中,用来表示边。node类的方法也只有获取编号和获取权值。
(2)nodefrom类带有的信息包括点的编号,名字,入度,出度,以及占领情况。nodefrom类中除了构造函数没有别的方法。仅作为一个点的抽象。
(3)edge类表示的是边,带有的信息有边的起点和终点还有边的权值,含有的方法是返回起点、返回终点、返回权值,以及输出边的信息。
(4)vertexIterator类在定义的时候作为抽象类被定义,之后在后面被继承实现里面的方法,方法就是将游标移到下一位。
(5)work类仅作为队伍的抽象保存队伍的编号,名字,入度,出度。work类中只有构造函数一个方法。
(6)works类表示的是队伍安排系统,主要的功能就是对队伍的顺序的安排,用到的算法是拓扑排序,里面的队伍用到的数据结构也是邻接数组,来表示队伍之间的先后顺序。该类中也有其他的基础方法,包括加点,删点,加边,删边,以及嵌在它们中的一些小方法。
(7)arrayWDgraph类是最重要的类,其他的类都被它调用。作为有向有权图的类,它带有的信息包括有顶点数、边数、边对应的邻接数组、点对应的栈。它里面的方法大致分为四种,第一种基于图的能够被别的方法调用的基础方法,用来获取点或边的一些信息。包括有获取编号为x的点的索引,获取点的个数、获取边的个数、判断是否存在点x、判断是否存在边(a,b)、判断点x是否合法、判断边(a,b)是否合法、判断占领值是否合法、获取入度、获取出度、获取度、是否为有向图、是否为有权图、获取文件中第一部分字符串、获取文件中第二部分字符串、获取文件中第三部分字符串、获取点的占领情况。第二种是对图修改的方法,包括有增加点、删除点、增加边、删除边、更新权值、更新占领值、100个点初始化、5个点初始化、清空图。第三种是算法相关的方法有拓扑排序、佛洛依德算法、深度优先算法。第四种是方便用户互动的方法,为其他算法服务,有打印路线、删除点和边、增加点和边等方面的引导的方法。
类
graph.h
#ifndef graph_
#define graph_
#include"edge.h"
#include"vertexIterator.h"
template<class T>
class graph
{
public:
virtual ~graph() {}
virtual int numberOfVertices() const = 0;//点的个数
virtual int numberOfEdges() const = 0;//边的个数
virtual bool existsEdge(int, int) const = 0;//判断是否存在从前面点到后面点的边
virtual void insertEdge(edge<T>*) = 0;//插入边
virtual bool eraseEdge(int, int) = 0;//删除边
virtual int degree(int) const = 0;//度
virtual int indegree(int) const = 0;//入度
virtual int outdegree(int) const = 0;//出度
virtual bool directed() const = 0;//方向
virtual bool weighted() const = 0;//权重
virtual vertexIterator<T>* iterator(int) = 0;//迭代器
};
#endif
edge.h
#pragma once
#ifndef edge_
#define edge_
#include<iostream>
using namespace std;
template<class T>
class edge {
public:
edge(int x=-1,int y=-1,T we=0) {
v1 = x;
v2 = y;
w = we;
}
~edge() {}
int getS1() {
return v1;//返回点1
}
int getS2() {
return v2;//返回点2
}
T getW() {
return w;//返回权值
}
void output() {
cout << "(" << v1 << "," << v2 << "," << w << ")";
}
private:
int v1;//点1
int v2;//点2
T w;//权值
};
#endif
node.h
#pragma once
#ifndef node_
#define node_
#include<iostream>
using namespace std;
template<class T>
class node {
public:
int number;//该点的编号
T weight;//权值
node(int num,int we=0) {
number = num;
weight = we;
}
int getn() {
return number;
}
int getw() {
return weight;
}
bool operator==(int y) {
if (y == this->number)return true;
else return false;
}
};
class nodeform {
public:
int ver;
int occupy;//用来判断该点是否已经占领
int indegree;//该点的入度
int outdegree;//该点的出度
string name;//该点所代表的地区的名字
nodeform(int oc = 0,int ve = 0, string na = "",int in = 0, int out = 0 )
{
occupy = oc;
name = na;
ver = ve;
indegree = in;
outdegree = out;
}
};
#endif
vertexIterator.h
#pragma once
#ifndef vertexIterator_
#define vertexIterator_
using namespace std;
template<class T>
class vertexIterator
{
public:
virtual ~vertexIterator() {}
virtual int next() = 0;
virtual int next(T&) = 0;
};
#endif
work.h
#pragma once
#ifndef work_
#define work_
#include<iostream>
#include<string>
#include<vector>
#include"node.h"
#include"edge.h"
#include<stack>
#include< fstream>
#include <sstream>
using namespace std;
class work {
public:
int ver;//队伍编号
int indegree;//该队伍的入度
int outdegree;//该队伍的出度
string name;//队伍名称
work(int ve = 0, string na = "", int in = 0, int out = 0)
{
name = na;
ver = ve;
indegree = in;
outdegree = out;
}
};
template<class T>
class works {
public:
struct VE {
int ve;
vector<node <T>> g;
};
vector<VE> E;//队伍先后联系图
vector<work> W;//队伍图
int num, edges;//分别是队伍数和队伍先后联系数
works(int v = 0)//构造函数
{
while (1)
{
if (v < 0)
{
cout << "输入不标准!请重新输入:" << endl;
cin >> v;
}
else
{
break;
}
}
num = v;
edges = 0;
W = vector<work>(num + 1);
E = vector<VE>{ (unsigned int)(num + 1),VE() };
}
~works() {}
//获取编号为x的队伍的索引
int reindex(int x) {
for (int i = 1; i <= num; i++)
{
if (W[i].ver == x)
{
return i;
}
}
}
//判断联系v1->v2是否合法
bool legaledge(int v1, int v2)
{
if (v1 < 1 || v2 < 1)
{
return false;
}
else
{
return true;
}
};
//判断队伍v是否合法
bool legalvertex(int v) {
if (v >= 1)
{
return true;
}
else
{
cout << "点不合法!" << endl;
return false;
}
}
//判断是否存在联系a->b
bool existsEdge(int a, int b) const {
int c = E[a].g.size();
for (int i = 0; i < c; i++)
{
if (E[a].g[i].number == b)
{
return true;
}
}
return false;
};
//判断是否已经存在队伍v
bool existvertex(int v)
{
for (int i = 0; i < W.size(); i++)
{
if (v == W[i].ver)
{
return true;
}
}
return false;
}
//增加队伍
void addvertex(int v, string na) {
work node(v, na);
W.push_back(node);
VE nod;
nod.ve = v;
nod.g.clear();
E.push_back(nod);
num++;
}
//删除队伍
void deletevertex(int v) {
int x = reindex(v);
int f = E[x].g.size();
E.erase(E.begin() + x, E.begin() + x + 1);
edges -= f;
W.erase(W.begin() + x, W.begin() + x + 1);
for (int i = 1; i < E.size(); i++)
{
for (int j = 0; j < E[i].g.size(); j++)
{
if (E[i].g[j].number == v)
{
E[i].g.erase(E[i].g.begin() + j, E[i].g.begin() + j + 1);
W[i].outdegree--;
edges--;
}
}
}
num--;
}
//增加联系
void insertEdge(edge<T>* Edge) {
int v1 = Edge->getS1();
int v2 = Edge->getS2();
if (!legaledge(v1, v2))
{
return;
}
int v = reindex(v1);
if (existsEdge(reindex(v1), v2))
{
auto p = E[v].g.begin();
for (int i = 0; i < E[v].g.size(); i++)
{
if (E[v].g[i].number == v2)
{
p = find(E[v].g.begin(), E[v].g.end(), v2);
}
}
}
else
{
W[reindex(v2)].indegree++;
W[v].outdegree++;
node<T> no(v2);
E[v].g.push_back(no);
edges++;
}
};
//删除联系
bool eraseEdge(int v1, int v2) {
int v = reindex(v1);
if (!legaledge(v1, v2))
{
return false;
}
if (!existsEdge(reindex(v1), v2))
{
return false;
}
for (int i = 0; i < E[v].g.size(); i++)
{
if (E[v].g[i].number == v2)
{
E[v].g.erase(remove(E[v].g.begin(), E[v].g.end(), v2), E[v].g.end());
W[v].outdegree--;
W[v].indegree--;
edges--;
break;
}
}
return true;
};
//返回第一部分的字符串
string first(string s) {
string f;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ')
{
f = s.substr(0, i + 1);
break;
}
}
return f;
}
//返回第二部分的字符串
string second(string s) {
string f;
int x;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ')
{
f = s.substr(i + 1, s.size() - i - 1);
}
}
return f;
}
//返回第一个空格位置的索引
int reoneblank(string s) {
int x;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ')
{
x = i;
break;
}
}
return x;
}
//在文件中写入点x
void advf(int x, string y) {
ofstream outfile;
outfile.open("workv.txt", ios::app);
outfile << x << " " << y << endl;
outfile.close();
}
//添加队伍
void adv()
{
system("cls");
cout << "当前功能为添加队伍" << endl;
int n;
cout << "请输入添加的队伍的个数:";
cin >> n;
int x;
string y;
for (int i = 0; i < n; i++)
{
cout << "请输入队伍的编号:";
while (1)
{
cin >> x;
if (!legalvertex(x))
{
cout << "输入不规范!请重新输入:";
continue;
}
else if (existvertex(x))
{
cout << " 该队伍已经存在!" << endl;
cout << "请重新输入:";
continue;
}
break;
}
cout << "请输入队伍的名字:";
cin >> y;
addvertex(x, y);
advf(x, y);
cout << "队伍" << x << "增加成功!" << endl;
break;
}
int a;
cout << "返回主页请按0 继续添加请按1" << endl;
cin >> a;
if (a)
{
adv();
}
else
{
return;
}
}
//添加队伍重载函数
void adv(int x)
{
string y;
cout << "请输入队伍的名字:";
cin >> y;
while (1)
{
if (legalvertex(x))
{
addvertex(x, y);
advf(x, y);
cout << "队伍" << x << "增加成功!" << endl;
break;
}
else
{
cout << "输入不规范,请重新输入:";
cin >> x;
continue;
}
}
}
//删除队伍的文件操作
void devf(int x) {
vector<string>vf;
string s;
fstream outfile;
outfile.open("workv.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (atoi(first(s).c_str()) != x && s != "")
{
vf.push_back(s);
}
}
outfile.close();
ofstream out("workv.txt");
out.close();
outfile.open("workv.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
vf.clear();
outfile.open("worke.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (s != "")
{
if (atoi(first(s).c_str()) != x && atoi(second(s).c_str()) != x)
{
vf.push_back(s);
}
}
}
outfile.close();
ofstream out1("worke.txt");
out1.close();
outfile.open("worke.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
}
//删除队伍
void dev()
{
system("cls");
cout << "当前功能为删除地点" << endl;
int n;
cout << "请输入删除地点的个数:";
cin >> n;
int x;
for (int i = 0; i < n; i++)
{
cout << "请输入删除地点的编号:";
while (1)
{
cin >> x;
if (existvertex(x))
{
deletevertex(x);
devf(x);
cout << "点" << x << "删除成功!" << endl;
break;
}
else
{
cout << "点" << x << "不存在!请重新输入:" << endl;
continue;
}
}
}
int a;
cout << "返回主页请按0 继续删除请按1" << endl;
cin >> a;
if (a)
{
dev();
}
else
{
return;
}
}
//在文件中写入边x->y
void adef(int x, int y) {
ofstream outfile;
outfile.open("worke.txt", ios::app);
outfile << x << " " << y << endl;
outfile.close();
}
//添加联系
void ade()
{
system("cls");
cout << "当前功能为添加联系" << endl;
int n;
cout << "请输入添加联系的个数:";
cin >> n;
int x, y;
for (int i = 0; i < n; i++)
{
while (1) {
cout << "请输入起始队伍:";
while (1) {
cin >> x;
if (legalvertex(x))
{
break;
}
else {
cout << "队伍不规范!请重新输入:" << endl;
}
}
if (!existvertex(x))
{
int p;
cout << "不存在队伍" << x << ",是否要添加队伍" << x << "?" << endl;
cout << "是请按1 否请按2" << endl;
cin >> p;
if (p == 1)
{
this->adv(x);
}
else
{
if (p == 2)
{
break;
}
}
}
cout << endl;
cout << "请输入终点队伍:";
while (1) {
cin >> y;
if (legalvertex(y))
{
break;
}
else {
cout << "队伍不规范!请重新输入:" << endl;
}
}
if (!existvertex(y))
{
int p;
cout << "不存在队伍" << y << ",是否要添加队伍" << y << "?" << endl;
cout << "是请按1 否请按2" << endl;
cin >> p;
if (p == 1)
{
this->adv(y);
}
else
{
if (p == 2)
{
break;
}
}
}
if (existsEdge(reindex(x), y)) {
cout << "已经存在该联系! " << endl;
continue;
}
else
{
edge<T>* ed = new edge<T>(x, y);
insertEdge(ed);
adef(x, y);
cout << "联系(" << x << "," << y << ")添加成功!" << endl;
break;
}
}
}
int a;
cout << "返回主页请按0 继续添加请按1" << endl;
cin >> a;
if (a)
{
ade();
}
else
{
return;
}
}
//删除边的文件操作
void deef(int x, int y) {
vector<string>vf;
string s;
fstream outfile;
outfile.open("worke.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (s != "")
{
if (atoi(first(s).c_str()) != x || atoi(second(s).c_str()) != y)
{
vf.push_back(s);
}
}
}
outfile.close();
ofstream out("worke.txt");
out.close();
outfile.open("worke.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
}
//删除联系
void dee()
{
system("cls");
cout << "当前功能为删除联系" << endl;
int n;
cout << "请输入删除联系的个数:";
cin >> n;
int x, y;
for (int i = 0; i < n; i++)
{
cout << "请输入起始队伍:";
while (1) {
cin >> x;
if (!existvertex(x))
{
cout << "不存在队伍" << x << endl;
cout << "请重新输入:";
}
else
{
break;
}
}
cout << "请输入终点队伍:";
while (1) {
cin >> y;
if (!existvertex(y))
{
cout << "不存在队伍" << y << endl;
cout << "请重新输入:";
}
else
{
break;
}
}
if (existsEdge(reindex(x), y))
{
eraseEdge(x, y);
deef(x, y);
}
cout << "边(" << x << "," << y << ")删除成功!" << endl;
}
int a;
cout << "返回主页请按0 继续删除请按1" << endl;
cin >> a;
if (a)
{
dee();
}
else
{
return;
}
}
//拓扑排序
int* Topologicalsorting() {
int* in = new int[num + 1];
int* result = new int[num + 1];
int* visited = new int[num + 1];
int j = 0;
int k = 0;
fill(visited, visited + num + 1, 0);
stack<int>zero;
for (int i = 1; i <= num; i++)
{
in[i] = W[i].indegree;
if (W[i].indegree == 0)
{
zero.push(i);
visited[i] = 1;
}
}
while (!zero.empty())
{
j = zero.top();
zero.pop();
result[k++] = W[j].ver;
for (int i = 0; i < E[j].g.size(); i++)
{
in[reindex(E[j].g[i].number)]--;
}
for (int i = 1; i <= num; i++)
{
if (visited[i] == 0 && in[i] == 0) {
zero.push(i);
visited[i] = 1;
}
}
}
for (int i = 1; i <= num; i++)
{
if (visited[i] == 0)
{
cout << "无法得出拓扑排序存在孤立点" << endl;
return result;
}
}
cout << "拓扑排序为:";
for (int i = 0; i < num - 1; i++) {
cout << W[reindex(result[i])].name << "->";
}
cout << W[reindex(result[num - 1])].name << endl;
}
//拓扑排序方法
void tuopu() {
system("cls");
cout << "当前功能为拓扑排序,为任务进行排序" << endl;
cout << "排序结果为:" << endl;
if (edges == 0)
{
for (int i = 1; i < W.size(); i++)
{
cout << W[i].ver << " ";
}
cout << endl;
cout << "返回主页面请按任意键" << endl;
system("pause");
return;
}
int* arr = Topologicalsorting();
cout << endl;
cout << "返回主页面请按任意键" << endl;
system("pause");
}
//文件流初始化
void Automaticinitialization() {
system("cls");
cout << "当前为自动初始化" << endl;
cout << "初始化中......." << endl;
fstream outfile;
outfile.open("workv.txt");
string s;
int x, y;
string na;
while (!outfile.eof())
{
getline(outfile, s);
if (s != "")
{
x = atoi(first(s).c_str());
na = second(s);
addvertex(x, na);
}
}
outfile.close();
fstream out;
out.open("worke.txt");
while (!out.eof())
{
getline(out, s);
if (s != "")
{
x = atoi(first(s).c_str());
y = atoi(second(s).c_str());
edge<T>* ed = new edge<T>(x, y);
insertEdge(ed);
}
}
out.close();
system("cls");
cout << "初始化完成" << endl;
system("pause");
}
//初始化
void initialization() {
int a;
bool flag = false;
while (1)
{
if (flag) {
break;
}
system("cls");
cout << "********************************" << endl;
cout << "**********队伍安排模块**********" << endl;
cout << "功能如下:" << endl;
cout << "1.增加队伍" << endl;
cout << "2.增加队伍联系" << endl;
cout << "3.删除队伍" << endl;
cout << "4.删除队伍联系" << endl;
cout << "5.队伍顺序安排" << endl;
cout << "6.自动初始化" << endl;
cout << "7.退出" << endl;
cout << "选择您需要的功能:" << endl;
cin >> a;
switch (a)
{
case 1:adv(); break;
case 2:ade(); break;
case 3:dev(); break;
case 4:dee(); break;
case 5:tuopu(); break;
case 6:Automaticinitialization(); break;
case 7:flag = true; break;
}
}
}
};
#endif
arrayWDigraph.h
#pragma once
#ifndef arrayWDigraph_
#define arrayWDigraph_
#include"graph.h"
#include"edge.h"
#include"node.h"
#include "vertexIterator.h"
#include"work.h"
#include<stack>
#include<string>
#include<vector>
#include<fstream>
#include <sstream>
#include<iostream>
template<class T>
class arrayWDgraph :public graph<T> {
protected:
struct VE {
int ve;
vector<node <T>> g;
};
const T mx = 10000;
int vertex;//顶点数
int edges;//边数
vector<VE> G;//存储图中的边
vector<nodeform>V;//存储图中的点
int* visited;//是否访问过
int length;//路径长度
int** pa;//佛洛依德的路径
T** dis;//佛洛依德的距离
int* dpath; //储存路径
//dijkstra专用
bool* canreach; //某点是否可达
T* ddis; //到某点的最少费用
stack<int>theShortest;
public:
//构造函数
arrayWDgraph(int v = 0) {
while (1)
{
if (v < 0)
{
cout << "输入不标准!请重新输入:" << endl;
cin >> v;
}
else
{
break;
}
}
vertex = v;
edges = 0;
visited = new int[vertex + 1];
V = vector<nodeform>(vertex + 1);
pa = NULL;
dis = NULL;
dpath = NULL;
ddis = NULL;
canreach = NULL;
G = vector<VE>{ (unsigned int)(vertex + 1),VE() };
};
~arrayWDgraph() {};
//string转化为T
T stringToNum(const string& str)
{
istringstream iss(str);
T num;
iss >> num;
return num;
}
//获取编号为x的点的索引
int reindex(int x) {
for (int i = 1; i <= vertex; i++)
{
if (V[i].ver == x)
{
return i;
}
}
}
//获取点的个数
int numberOfVertices() const {
return vertex;
};
//获取边的个数
int numberOfEdges() const {
return edges;
};
//判断是否存在边a->b
bool existsEdge(int a, int b) const {
int c = G[a].g.size();
for (int i = 0; i < c; i++)
{
if (G[a].g[i].number == b)
{
return true;
}
}
return false;
};
//判断是否已经存在点v
bool existvertex(int v)
{
for (int i = 0; i < V.size(); i++)
{
if (v == V[i].ver)
{
return true;
}
}
return false;
}
//判断边v1->v2是否合法
bool legaledge(int v1, int v2)
{
if (v1 < 1 || v2 < 1)
{
return false;
}
else
{
return true;
}
};
//判断点v是否合法
bool legalvertex(int v) {
if (v >= 1)
{
return true;
}
else
{
cout << "点不合法!" << endl;
return false;
}
}
//用来判断输入的占领值是否合法
bool legaloccupy(int x) {
if (x == 1 || x == 0)
{
return true;
}
return false;
}
//判断权值是否合法
bool legalweight(T w) {
if (w < 0)
{
return false;
}
else
{
return true;
}
}
//增加边
void insertEdge(edge<T>* Edge) {
int v1 = Edge->getS1();
int v2 = Edge->getS2();
T w = Edge->getW();
if (!legaledge(v1, v2))
{
return;
}
int v = reindex(v1);
if (existsEdge(reindex(v1), v2))
{
auto p = G[v].g.begin();
for (int i = 0; i < G[v].g.size(); i++)
{
if (G[v].g[i].number == v2)
{
p = find(G[v].g.begin(), G[v].g.end(), v2);
}
}
p->weight = w;
}
else
{
V[reindex(v2)].indegree++;
V[v].outdegree++;
node<T> no(v2, w);
G[v].g.push_back(no);
edges++;
}
};
//删除边
bool eraseEdge(int v1, int v2) {
int v = reindex(v1);
if (!legaledge(v1, v2))
{
return false;
}
if (!existsEdge(reindex(v1), v2))
{
return false;
}
for (int i = 0; i < G[v].g.size(); i++)
{
if (G[v].g[i].number == v2)
{
G[v].g.erase(remove(G[v].g.begin(), G[v].g.end(), v2), G[v].g.end());
V[v].outdegree--;
V[v].indegree--;
edges--;
break;
}
}
return true;
};
//获取入度
int indegree(int v) const {
return V[v].indegree;
};
//获取入度子方法
int idg(int x) {
return indegree(reindex(x));
}
//获取出度
int outdegree(int v) const {
return V[v].outdegree;
};
//获取出度子方法
int odg(int x) {
return outdegree(reindex(x));
}
//获取度
int degree(int v) const {
return indegree(v) + outdegree(v);
};
//是否为有向图
bool directed() const { return true; };
//是否为有权图
bool weighted() const { return true; };
//被DFS调用
void rDFS(int start, int label) {
visited[start] = label;
auto pointer = iterator(start);
int now;
while ((now = pointer->next()) != 0) {
if (visited[now] == 0)
rDFS(now, label);
}
delete pointer;
}
//被dfs调用
void sdfs(int start, int label) {
visited[start] = label;
auto pointer = G[start].g.begin();
int now;
while (pointer != G[start].g.end()) {
now = pointer->number;
if (visited[now] == 0)
sdfs(now, label);
pointer++;
}
}
//迭代器的继承
class myIterator : public vertexIterator<T> {
public:
myIterator(VE& thelist) {//传入引用,减小开销
newlist = thelist.g;
size = newlist.size() - 1;//初始化
cur = 0;
};
int next() {//取出当前,指向后一个
if (cur > size)return 0;//终止
int nextVertex = newlist[cur].number;//取出权值和下标
cur++;//游标后移
return nextVertex;
};
int next(T& theWeight) {
if (cur > size)return 0; //终止
int nextVertex = newlist[cur].number;//取出权值和下标
theWeight = newlist[cur].weight;
cur++;//游标后移
return nextVertex;
};
int next(T& theWeight, int& pos) {
if (cur > size)return 0; //终止
int nextVertex = newlist[cur].number;//取出权值和下标
theWeight = newlist[cur].weight;
pos = cur++;//游标后移
return nextVertex;
};
void reset() { cur = 0; }//重置游标
protected:
vector<node<T>>newlist;
int x;
int cur;
int size;
};
//迭代器的方法
myIterator* iterator(int x) {
if (legalvertex(x)) {
return new myIterator(G[reindex(x)]);//为类中传入边表,因为该类无法使用主类中的nodes
}
};
//自带的迭代器dfs
void dfs(int start, int label) {
if (!legalvertex(start))return;
visited = new int[vertex + 1];
fill(visited, visited + vertex + 1, 0);
sdfs(start, label);
}
//课本的迭代器的DFS
void DFS(int start, int label) {
if (!legalvertex(start))return;
visited = new int[vertex + 1];
fill(visited, visited + vertex + 1, 0);
rDFS(start, label);
}
//返回第一部分的字符串
string first(string s) {
string f;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ')
{
f = s.substr(0, i + 1);
break;
}
}
return f;
}
//返回第二部分的字符串
string second(string s) {
string f;
bool flag = false;
int x;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ' && !flag)
{
flag = true;
x = i;
}
else
{
if (s[i] == ' ' && flag)
{
f = s.substr(x + 1, i - x);
break;
}
}
}
return f;
}
//返回第三部分的字符串
string third(string s) {
string f;
bool flag = false;
int x;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ' && !flag)
{
flag = true;
x = i;
}
else
{
if (s[i] == ' ' && flag)
{
f = s.substr(i + 1, s.size() - i - 1);
break;
}
}
}
return f;
}
//返回第一个空格位置的索引
int reoneblank(string s) {
int x;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ')
{
x = i;
break;
}
}
return x;
}
//返回第二个空格的位置的索引
int retwoblank(string s) {
int x;
bool flag = false;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == ' ' && !flag)
{
flag = true;
}
else
{
if (s[i] == ' ' && flag)
{
x = i;
break;
}
}
}
return x;
}
//在文件中更新权值
void updwf(int x, int y, T z) {
vector<string>vf;
string s;
fstream outfile;
outfile.open("edges.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (atoi(first(s)) == x && atoi(second(s)) == y)
{
s = s.substr(0, retwoblank(s));
string c = to_string(z);
s += c;
vf.push_back(s);
}
else
{
if (s != "")
{
vf.push_back(s);
}
}
}
outfile.close();
ofstream out("edges.txt");
out.close();
outfile.open("edges.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
}
//更新权值
void updateweight(int v1, int v2, T w) {
int c = G[reindex(v1)].g.size();
for (int i = 0; i < c; i++)
{
if (G[reindex(v1)].g[i].number == v2)
{
G[reindex(v1)].g[i].weight = w;
}
}
cout << "更新成功!" << endl;
int a;
cout << "返回主页请按0 继续添加请按1" << endl;
cin >> a;
switch (a) {
case 1:ade(); break;
case 0:return;
}
}
//增加点
void addvertex(int v, string na, int ocu = 0) {
nodeform node(ocu, v, na);
V.push_back(node);
VE nod;
nod.ve = v;
nod.g.clear();
G.push_back(nod);
vertex++;
}
//删除点
void deletevertex(int v) {
int x = reindex(v);
int num = G[x].g.size();
G.erase(G.begin() + x, G.begin() + x + 1);
edges -= num;
V.erase(V.begin() + x, V.begin() + x + 1);
vertex--;
for (int i = 1; i < G.size(); i++)
{
for (int j = 0; j < G[i].g.size(); j++)
{
if (G[i].g[j].number == v)
{
G[i].g.erase(G[i].g.begin() + j, G[i].g.begin() + j + 1);
V[i].outdegree--;
}
}
}
}
//在文件中写入点x
void advf(int x, string y, int z) {
ofstream outfile;
outfile.open("vertex.txt", ios::app);
outfile << x << " " << y << " " << z << endl;
outfile.close();
}
//添加地点
void adv()
{
system("cls");
cout << "当前功能为添加地点" << endl;
int n;
cout << "请输入添加的点的个数:";
cin >> n;
int x, o;
string y;
for (int i = 0; i < n; i++)
{
cout << "请输入点的编号:";
while (1)
{
cin >> x;
if (!legalvertex(x))
{
cout << "请重新输入:";
continue;
}
else if (existvertex(x))
{
cout << " 该点已经存在!" << endl;
cout << "请重新输入:";
continue;
}
break;
}
cout << "请输入点的名字:";
cin >> y;
cout << "该点是否已经被占领(0为否,1为是):";
cin >> o;
while (1)
{
if (legaloccupy(o))
{
addvertex(x, y, o);
advf(x, y, o);
cout << "点" << x << "增加成功!" << endl;
break;
}
else
{
cout << "输入不规范,请重新输入:";
cin >> o;
}
}
}
int a;
cout << "返回主页请按0 继续添加请按1" << endl;
cin >> a;
switch (a) {
case 1:adv(); break;
case 0:return;
}
}
//添加地点重载函数
void adv(int x)
{
string y;
int o;
cout << "请输入点的名字:";
cin >> y;
cout << "该点是否已经被占领(0为否,1为是):";
cin >> o;
while (1)
{
if (legaloccupy(o))
{
addvertex(x, y, o);
advf(x, y, o);
cout << "点" << x << "增加成功!" << endl;
break;
}
else
{
cout << "输入占领情况不规范,请重新输入:";
cin >> o;
continue;
}
}
}
//删除点的文件操作
void devf(int x) {
vector<string>vf;
string s;
fstream outfile;
outfile.open("vertex.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (atoi(first(s).c_str()) != x && s != "")
{
vf.push_back(s);
}
}
outfile.close();
ofstream out("vertex.txt");
out.close();
outfile.open("vertex.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
vf.clear();
outfile.open("edges.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (s != "")
{
if (atoi(first(s).c_str()) != x && atoi(second(s).c_str()) != x)
{
vf.push_back(s);
}
}
}
outfile.close();
ofstream out1("edges.txt");
out1.close();
outfile.open("edges.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
}
//删除地点
void dev()
{
system("cls");
if (vertex == 0)
{
cout << "一个点也没有!" << endl;
system("pause");
return;
}
else
{
cout << "当前功能为删除地点" << endl;
int n;
cout << "请输入删除地点的个数:";
cin >> n;
int x;
for (int i = 0; i < n; i++)
{
cout << "请输入删除地点的编号:";
cin >> x;
deletevertex(x);
devf(x);
cout << "点" << x << "删除成功!" << endl;
}
int a;
cout << "返回主页请按0 继续删除请按1" << endl;
cin >> a;
switch (a) {
case 1:dev(); break;
case 0:return;
}
}
}
//在文件中写入边x->y
void adef(int x, int y, T z) {
ofstream outfile;
outfile.open("edges.txt", ios::app);
outfile << x << " " << y << " " << z << endl;
outfile.close();
}
//添加路
void ade()
{
system("cls");
cout << "当前功能为添加路" << endl;
int n;
cout << "请输入添加路的个数:";
cin >> n;
int x, y;
T w;
for (int i = 0; i < n; i++)
{
cout << "请输入起点:";
while (1) {
cin >> x;
if (legalvertex(x))
{
break;
}
else {
cout << "点不规范!请重新输入:" << endl;
}
}
if (!existvertex(x))
{
int p;
cout << "不存在点" << x << ",是否要添加点" << x << "?" << endl;
cout << "是请按1 否请按2" << endl;
cin >> p;
switch (p) {
case 1:this->adv(x); break;
case 2:return;
}
}
cout << endl;
cout << "请输入终点:";
while (1) {
cin >> y;
if (legalvertex(y))
{
break;
}
else {
cout << "点不规范!请重新输入:" << endl;
}
}
if (!existvertex(y))
{
int p;
cout << "不存在点" << y << ",是否要添加点" << y << "?" << endl;
cout << "是请按1 否请按2" << endl;
cin >> p;
switch (p) {
case 1:this->adv(y); break;
case 2:return;
}
}
if (existsEdge(reindex(x), y)) {
cout << "已经存在该路径,是否要更新权值? 否请按0,是请按1 " << endl;
int p;
cin >> p;
switch (p)
{
case 0:return;
case 1: {cout << "请输入路径的权值:";
while (1)
{
cin >> w;
if (legalweight(w))
{
break;
}
else
{
cout << "输入的权值不规范!请重新输入:" << endl;
}
}
updateweight(x, y, w);
return; }
}
}
cout << "请输入路径的权值:";
while (1)
{
cin >> w;
if (legalweight(w))
{
break;
}
else
{
cout << "输入的权值不规范!请重新输入:" << endl;
}
}
edge<T>* ed = new edge<T>(x, y, w);
insertEdge(ed);
adef(x, y, w);
cout << "边";
ed->output();
cout << "添加成功!" << endl;
}
int a;
cout << "返回主页请按0 继续添加请按1" << endl;
cin >> a;
switch (a) {
case 0:return;
case 1:ade(); break;
}
}
//删除路的文件操作
void deef(int x, int y) {
vector<string>vf;
string s;
fstream outfile;
outfile.open("edges.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (s != "")
{
if (atoi(first(s).c_str()) != x || atoi(second(s).c_str()) != y)
{
vf.push_back(s);
}
}
}
outfile.close();
ofstream out("edges.txt");
out.close();
outfile.open("edges.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
}
//删除路
void dee()
{
system("cls");
if (edges == 0)
{
cout << "当前不存在路!" << endl;
system("pause");
return;
}
cout << "当前功能为删除路" << endl;
int n;
cout << "请输入删除路的个数:";
cin >> n;
int x, y;
for (int i = 0; i < n; i++)
{
cout << "请输入起点:";
while (1) {
cin >> x;
if (!existvertex(x))
{
cout << "不存在点" << x << endl;
cout << "请重新输入:";
}
else
{
break;
}
}
cout << "请输入终点:";
while (1) {
cin >> y;
if (!existvertex(y))
{
cout << "不存在点" << y << endl;
cout << "请重新输入:";
}
else
{
break;
}
}
if (existsEdge(reindex(x), y))
{
eraseEdge(x, y);
deef(x, y);
}
cout << "边(" << x << "," << y << ")删除成功!" << endl;
}
return;
}
//拓扑排序
void Topologicalsorting() {
int* in = new int[vertex + 1];
int* result = new int[vertex + 1];
int j = 0;
int k = 0;
visited= new int[vertex + 1];
fill(visited, visited + vertex + 1, 0);
stack<int>zero;
for (int i = 1; i <= vertex; i++)
{
in[i] = V[i].indegree;
if (V[i].indegree == 0)
{
zero.push(i);
visited[i] = 1;
}
}
while (!zero.empty())
{
j = zero.top();
zero.pop();
result[k++] = V[j].ver;
for (int i = 0; i < G[j].g.size(); i++)
{
in[reindex(G[j].g[i].number)]--;
}
for (int i = 1; i <= vertex; i++)
{
if (visited[i] == 0 && in[i] == 0) {
zero.push(i);
visited[i] = 1;
}
}
}
for (int i = 1; i <= vertex; i++)
{
if (visited[i] == 0)
{
cout << "无法得出拓扑排序!出现点之间的关系无法拓扑!" << endl;
return;
}
}
cout << "拓扑排序为:";
for (int i = 0; i < vertex - 1; i++) {
cout << V[reindex(result[i])].name << "->";
}
cout << V[reindex(result[vertex - 1])].name << endl;
}
//拓扑排序方法
void tuopu() {
system("cls");
if (vertex == 0)
{
cout << "一个点也没有!" << endl;
system("pause");
return;
}
cout << "当前功能为拓扑排序,为地点进行排序" << endl;
cout << "排序结果为:" << endl;
if (edges == 0)
{
for (int i = 1; i < V.size(); i++)
{
cout << V[i].ver << " ";
}
cout << endl;
cout << "返回主页面请按任意键" << endl;
system("pause");
return;
}
Topologicalsorting();
cout << endl;
system("pause");
}
//更该点的占领情况的文件操作
void alterocf(int x) {
vector<string>vf;
string s, n;
fstream outfile;
outfile.open("vertex.txt");
while (!outfile.eof())
{
getline(outfile, s);
if (s[0] - '0' == x && s != "")
{
n = s.substr(0, 4);
if (s[4] - '0' == 0)
{
n += "1";
}
else
{
n += "0";
}
vf.push_back(n);
}
else
{
vf.push_back(s);
}
}
outfile.close();
ofstream out("vertex.txt");
out.close();
outfile.open("vertex.txt", ios::app);
for (int i = 0; i < vf.size(); i++)
{
outfile << vf[i] << endl;
}
outfile.close();
}
//更改点的占领情况的文件操作
void alteroc(int x) {
if (V[x].occupy)
{
V[x].occupy = 0;
}
else
{
V[x].occupy = 1;
}
}
//更改点的占领情况
void addoc() {
system("cls");
if (vertex == 0)
{
cout << "一个点也没有!" << endl;
system("pause");
return;
}
cout << "当前功能为更改点的占领情况" << endl;
cout << "请输入要更改的点的编号:";
int x;
cin >> x;
while (1)
{
if (!existvertex(x))
{
cout << "目标点不存在!请重新输入:";
cin >> x;
continue;
}
if (V[reindex(x)].occupy) {
cout << "点" << x << "当前的占领情况为:已被占领" << endl;
}
else
{
cout << "点" << x << "当前的占领情况为:未被占领" << endl;
}
cout << "是否要更改占领情况?(是请按1 否请按0)" << endl;
int p;
cin >> p;
switch (p)
{
case 1: {alteroc(reindex(x));
alterocf(x);
cout << "更改成功!" << endl;
system("pause");
return; }
case 0:return;
}
}
system("pause");
}
//连通集
void Connected() {
visited = new int[vertex + 1];
fill(visited, visited + vertex + 1, 0);
int a, b;
b = 0;
vector<vector<int>>lian;
stack<int>sl;
vector<int>du;
for (int i = 1; i <= vertex; i++)
{
if (visited[i] == 0&&V[i].occupy==1)
{
sl.push(i);
du.push_back(i);
visited[i] = 1;
}
while (!sl.empty())
{
a = sl.top();
sl.pop();
for (int j = 0; j < G[a].g.size(); j++)
{
int re = reindex(G[a].g[j].number);
if (visited[re] == 0 && V[re].occupy == 1)
{
sl.push(re);
du.push_back(re);
visited[re] = 1;
}
}
}
if (!du.empty()) {
lian.push_back(du);
b++;
du.clear();
}
}
if (!lian.empty())
{
cout << "已经占领了的点的连通集:" << endl;
for (int i = 0; i < b; i++) {
int x = 0;
cout << "第" << i + 1 << "部分:";
while (x<lian[i].size()) {
cout << V[lian[i][x++]].ver << " ";
}
cout << endl;
}
cout << endl;
}
else
{
cout << "没有已占领的点!" << endl;
}
lian.clear();
b = 0;
for (int i = 1; i <= vertex; i++)
{
if (visited[i] == 0 && V[i].occupy == 0)
{
sl.push(i);
du.push_back(i);
visited[i] = 1;
}
while (!sl.empty())
{
a = sl.top();
sl.pop();
for (int j = 0; j < G[a].g.size(); j++)
{
int re = reindex(G[a].g[j].number);
if (visited[re] == 0 && V[re].occupy == 0)
{
sl.push(re);
du.push_back(re);
visited[re] = 1;
}
}
}
if (!du.empty()) {
lian.push_back(du);
b++;
du.clear();
}
}
if (!lian.empty())
{
cout << "未占领的点的连通集:" << endl;
for (int i = 0; i < b; i++) {
int x = 0;
cout << "第" << i + 1 << "部分:";
while (x < lian[i].size()) {
cout << V[lian[i][x++]].ver << " ";
}
cout << endl;
}
cout << endl;
}
else
{
cout << "没有未占领的点!" << endl;
}
}
//每个点的占领情况
void everyoc() {
system("cls");
if (vertex == 0)
{
cout << "一个点也没有!" << endl;
system("pause");
return;
}
for (int i = 1; i < V.size(); i++)
{
cout << "编号:" << V[i].ver << "占领情况:";
if (V[i].occupy)cout << "已占领" << endl;
else cout << "未占领" << endl;
}
Connected();
system("pause");
}
//打印最短路径子方法
void print_path(int i, int j) {
int k = pa[i][j];
if (k == -1)
//说明没有中转顶点,直接返回.
return;
print_path(i, k);//寻找i和k之间
cout << V[k].ver << "->";
print_path(k, j);//寻找k和j之间
}
//打印最短路径
void print_result() {
int i, j;
for (i = 1; i < vertex + 1; i++) {
for (j = 1; j < vertex + 1; j++) {
if (dis[i][j] == mx) {
//无法到达设置距离为无穷大,则他们之前没有路径
cout << V[i].ver << "和" << V[j].ver << "之间没有路径" << endl;
}
else {
cout << V[i].ver << "和" << V[j].ver << "的最短路径为" << dis[i][j] << endl;
cout << "路径方案为:" << V[i].ver << "->";
print_path(i, j);
cout << V[j].ver << endl;
}
}
}
}
//佛洛依德算法
void floyed() {
dis = new T * [vertex + 1];
for (int i = 0; i < vertex + 1; i++)
{
dis[i] = new T[vertex + 1];
}
pa = new int* [vertex + 1];
for (int i = 0; i < vertex + 1; i++)
{
pa[i] = new int[vertex + 1];
for (int j = 0; j < vertex + 1; j++)
{
pa[i][j] = -1;
}
}
for (int i = 0; i < vertex + 1; i++) {
for (int j = 0; j < vertex + 1; j++) {
if (i == j)dis[i][j] = 0;
else dis[i][j] = mx;
}
}
for (int i = 1; i < G.size(); i++)
{
for (int j = 0; j < G[i].g.size(); j++)
{
dis[i][reindex(G[i].g[j].number)] = G[i].g[j].weight;
}
}
for (int k = 1; k < vertex + 1; k++) {
//不断插点
for (int i = 1; i < vertex + 1; i++) {
for (int j = 1; j < vertex + 1; j++) {
//对图中所有点之间的最短距离进行更新。
if (dis[i][j] > dis[i][k] + dis[k][j]) {
pa[i][j] = k;//记录中转顶点。
dis[i][j] = dis[i][k] + dis[k][j];//更新。
}
}
}
}
}
//最短路径方法
void foluo() {
system("cls");
if (vertex == 0)
{
cout << "图中没有点!" << endl;
system("pause");
return;
}
cout << "当前功能为每个地点间的最短路径" << endl;
cout << "结果为:";
floyed();
print_result();
cout << "***************************" << endl;
system("pause");
}
//迪杰斯特拉算法
void rdijkstra(int start)
{
int cnt = 1;
for (int i = 1; i <= vertex - 1; i++) {//更新n-1次
T min = mx;
int minnode = 0;
for (int j = 1; j <= vertex; j++) {//j是下标
if (ddis[j] < min && visited[j] == 0) {
min = ddis[j];
minnode = V[j].ver;//中转点的编号
}
}
if (minnode == 0)
{
continue;
}//没有可更新的点
//path[minnode] = start;
//没有路径的情况
visited[reindex(minnode)] = 1;//已找到到达minnode的最短路径
auto pointer = iterator(minnode);
int next, pos;
T weight;
while ((next = pointer->next(weight, pos)) != 0) {
if (visited[reindex(next)] == 0 && ddis[reindex(next)] > G[reindex(minnode)].g[pos].weight + ddis[reindex(minnode)]) {
ddis[reindex(next)] = G[reindex(minnode)].g[pos].weight + ddis[reindex(minnode)];
dpath[reindex(next)] = reindex(minnode);
}
}
}
}
T* short_path_dijkstra(int start, int end)
{
ddis = new T[vertex + 1];
fill(ddis, ddis + vertex + 1, mx);
ddis[0] = vertex;
ddis[start] = 0;
dpath = new int[vertex + 1];
dpath[start] = start;
visited= new int[vertex + 1];
fill(visited, visited + vertex + 1, 0);
visited[start] = 1;
auto pointer = iterator(V[start].ver);
int next;
T weight;
while ((next = pointer->next(weight)) != 0) {
ddis[reindex(next)] = weight;
dpath[reindex(next)] = start;
}
rdijkstra(start);
canreach = new bool[vertex + 1];
for (int i = 1; i <= vertex; i++)
{
canreach[i] = true;
if (ddis[i] == mx)
{
canreach[i] = false;
}
}
if (canreach[end] == false)
{
return NULL;
}
stack<int>nothing;
theShortest.swap(nothing);
int cnt = 0;
while (end != start) {
theShortest.push(end);
cnt++;
end = dpath[end];
}
ddis[0] = cnt;
canreach = NULL;
return ddis;
}
void dijkstra_result(int start, int end)
{
start = reindex(start);//转换为索引
end = reindex(end);
T* distance = short_path_dijkstra(start, end);
if (!distance) {
cout << "不存在从" << V[start].ver << "到" << V[end].ver << "的路径" << endl;
return;
}
T mindis = distance[0];
cout << "从" << V[start].ver << "到" << V[end].ver << "的最短路径为" << ddis[end] << endl;
cout << "其路径为:" << V[start].ver << "->";
for (int i = 1; i <= mindis; i++)
{
cout << V[theShortest.top()].ver;
if (i != mindis)
{
cout << "->";
}
theShortest.pop();
}
cout << endl;
}
void dijkstra()
{
system("cls");
cout << "当前功能为单点最短路径" << endl;
cout << "请输入作为单点的起点编号:" << endl;
int qidian = 0;
int zhongdian = 0;
while (1) {
cin >> qidian;
if (!existvertex(qidian))
{
cout << "输入的起点不存在,请重新输入!" << endl;
}
else
{
break;
}
}
cout << "请输入作为单点的终点编号:" << endl;
while (1) {
cin >> zhongdian;
if (!existvertex(zhongdian))
{
cout << "输入的起点不存在,请重新输入!" << endl;
}
else
{
break;
}
}
if (qidian == zhongdian)
{
cout << "输入的起点与终点一致!" << endl;
system("pause");
return;
}
else {
dijkstra_result(qidian, zhongdian);
}
system("pause");
}
//队伍模块
void ranks() {
works<double>K(0);
K.initialization();
}
//清空图
void allclear() {
system("cls");
if (vertex == 0)
{
cout << "图中没有点!" << endl;
system("pause");
return;
}
system("cls");
cout << "正在清空......." << endl;
G.clear();
V.clear();
vertex = 0;
edges = 0;
visited = new int[vertex + 1];
V = vector<nodeform>(vertex + 1);
pa = NULL;
dis = NULL;
dpath = NULL;
ddis = NULL;
canreach = NULL;
G = vector<VE>{ (unsigned int)(vertex + 1),VE() };
system("cls");
cout << "清空完成" << endl;
system("pause");
}
//文件流初始化
void Automaticinitialization() {
system("cls");
if (vertex != 0)
{
cout << "图还未清空,请勿初始化!" << endl;
cout << "是否要清空图?是请按1,否请按0" << endl;
int a;
cin >> a;
switch (a)
{
case 1:allclear(); break;
case 0:return;
}
}
system("cls");
cout << "当前为自动初始化" << endl;
cout << "初始化中......." << endl;
fstream outfile;
outfile.open("vertex.txt");
string s;
int x, y, z;
string na;
while (!outfile.eof())
{
getline(outfile, s);
if (s != "")
{
x = atoi(first(s).c_str());
na = second(s);
z = atoi(third(s).c_str());
addvertex(x, na, z);
}
}
outfile.close();
fstream out;
out.open("edges.txt");
string c;
while (!out.eof())
{
getline(out, s);
if (s != "")
{
x = atoi(first(s).c_str());
y = atoi(second(s).c_str());
c = third(s);
T p = stringToNum(c);
edge<T>* ed = new edge<T>(x, y, p);
insertEdge(ed);
}
}
out.close();
system("cls");
cout << "初始化完成" << endl;
system("pause");
}
//初始化5个点
void Ainitialization() {
system("cls");
if (vertex != 0)
{
cout << "图还未清空,请勿初始化!" << endl;
cout << "是否要清空图?是请按1,否请按0" << endl;
int a;
cin >> a;
switch (a)
{
case 1:allclear(); break;
case 0:return;
}
}
system("cls");
cout << "当前为自动初始化" << endl;
cout << "初始化中......." << endl;
fstream outfile;
outfile.open("vertex2.txt");
string s;
int x, y, z;
string na;
while (!outfile.eof())
{
getline(outfile, s);
if (s != "")
{
x = atoi(first(s).c_str());
na = second(s);
z = atoi(third(s).c_str());
addvertex(x, na, z);
}
}
outfile.close();
fstream out;
out.open("edges2.txt");
string c;
while (!out.eof())
{
getline(out, s);
if (s != "")
{
x = atoi(first(s).c_str());
y = atoi(second(s).c_str());
c = third(s);
T p = stringToNum(c);
edge<T>* ed = new edge<T>(x, y, p);
insertEdge(ed);
}
}
out.close();
system("cls");
cout << "初始化完成" << endl;
system("pause");
}
//性能测试
void performCompare() {
//定制的
system("cls");
if (vertex == 0)
{
cout << "请先初始化!" << endl;
system("pause");
return;
}
system("cls");
cout << "测试中........." << endl;
clock_t start1, finish1;
int label = 1, count1 = 0;
start1 = clock();
do
{
DFS(1, label);
count1++;
} while (((finish1 = clock()) - start1) < 1000);
double x1 = ((double)finish1 - (double)start1) / count1;
//自带的
label = 1;
int n = 0;
clock_t start2, finish2;
int count2 = 0;
start2 = clock();
do
{
dfs(1, label);
count2++;
} while (((finish2 = clock()) - start2) < 1000);
double x2 = ((double)finish2 - (double)start2) / count2;
system("cls");
cout << "课本DFS运行时间:" << x1 << endl << "定制的的DFS运行时间:" << x2 << endl;
system("pause");
}
//初始化
void initialization() {
bool flag = false;
while (1)
{
int a;
if (flag) {
break;
}
system("cls");
cout << "********************************" << endl;
cout << "**********军事信息系统**********" << endl;
cout << "功能如下:" << endl;
cout << "1.增加地点" << endl;
cout << "2.增加路" << endl;
cout << "3.删除地点" << endl;
cout << "4.删除路" << endl;
cout << "5.更改点的占领情况" << endl;
cout << "6.地点拓扑安排" << endl;
cout << "7.单点最短路径" << endl;
cout << "8.所有地点间最短路径" << endl;
cout << "9.每个点的占领情况" << endl;
cout << "10.队伍安排模块" << endl;
cout << "11.自动初始化(100个点)" << endl;
cout << "12.自动初始化(5个点)" << endl;
cout << "13.清空全部" << endl;
cout << "14.性能测试" << endl;
cout << "15.退出" << endl;
cout << "选择您需要的功能:" << endl;
cin >> a;
switch (a)
{
case 1:adv(); break;
case 2:ade(); break;
case 3:dev(); break;
case 4:dee(); break;
case 5:addoc(); break;
case 6:tuopu(); break;
case 7:dijkstra(); break;
case 8:foluo(); break;
case 9:everyoc(); break;
case 10:ranks(); break;
case 11:Automaticinitialization(); break;
case 12:Ainitialization(); break;
case 13:allclear(); break;
case 14:performCompare(); break;
case 15:flag = true; break;
}
}
}
};
#endif
主函数文件
#include <iostream>
#include "arrayWDigraph.h"
int main()
{
arrayWDgraph<double> W(0);
W.initialization();
return 0;
}
使用的算法(数据结构)
1.拓扑排序
2.佛洛依德算法
3.迪杰斯特拉算法
4.深度优先算法
5.广度优先算法
6.采用邻接数组的方式存储有向有权图
交互
该项目采用文件流的方式,交互所对应的结果会反映到文件中去。