C++实现有向权图的基本操作,界面友好,操作方便,运行流畅
Ⅰ.功能: .创建图
.展示全图
.添加顶点
.添加边
.删除顶点
.删除边
.查看指定边权值
.修改指定边权值
.输出两点间的所有简单路及路径对应权值
.销毁图
ps:关于9,如果不存在任何简单路,输出“不存在任何简单路”。简单路:不含重复顶点的路。如
5是简单路, 5不是简单路。可以想见,对于大多数问题,非简单路是没有
研究意义的。如从北京到上海的路线,多次经过同一地点的路线是没有研究价值的。
Ⅱ.不足:
.代码冗长,复用率低。原因是有些操作基本相同但又有细微不同(如goto mark6;goto
mark7;),难以封装成一个函数。在此请求大神给出好的解决办法。
.类的成员函数的实现也写在了头文件中,使头文件过长。原因是前几次代码使用了模板,(看
过在下前几篇博文的读者应该知道)而用模板的话,就要求要么将类的成员函数的实现和类放
在一起,要么放在main函数中(尽管听有人说《C++Primer》中说不这样也行,但在下实测的 结果是——必须这样)。在下写习惯了,写完后才发现对于此次代码,将类的成员函数的实现
另放一个文件好。但代码已经写完,就暂时不改了,万一再改出bug来,没准又得调半天,这里
和大家说一声,求原谅。
.使用了goto语句(前几次也一样),有人对goto严格禁止,但依在下愚见,小范围内使用还是
可以的,再说,在下也是迫不得已,实在没有更好的办法了。还是那句话,求大神指教。
.时空复杂性较高,特别是时间复杂性,懂这方面的读者一看在下的代码便知。主要是顶点和边
都是用链表实现的,动不动就要遍历,但话说回来,至今在下还没找到比用链表实现更好的方
法,还请高人指教。
Ⅲ.优点:
.程序在多处用了控制,保证了程序的健壮性和友好,可重复操作,体验良好。
.仅提供Operate()函数一个接口,较大限度地实现了封装。
Ⅳ.博主推荐
.找两点间所有简单路并输出路径总权值有一定思维量和技巧性,有兴趣的读者可自行分析相
关代码,体会其思想。此代码为本人原创(当然不排除读者在其它地方见到相似代码,尽管在
下未参考任何书籍或网络资源)。
Ⅴ.代码:
//.h文件
#ifndef GRAPH_H
#define GRAPH_H
#include<iostream>
#include<iomanip>
using namespace std; struct Edge //边结构体
{
int egnum; //结点编号
int weight; //权值
Edge* enext; //下一边结点
Edge(int enm, int wgt, Edge* enxt);
};
Edge::Edge(int enm, int wgt, Edge* enxt) //边结构体构造函数
{
egnum = enm;
weight = wgt;
enext = enxt;
} struct Vertices //顶点结构体
{
int number; //结点编号
Edge* state; //顶点状态,用于标记顶点是否被遍历
Edge* eghead; //边链表头结点
Vertices* vnext; //下一顶点结点
Vertices(int num,Edge* sta, Edge* eghed, Vertices* vnxt);
};
Vertices::Vertices(int num,Edge* sta,Edge* eghed, struct Vertices* vnxt) //顶点结构体构造函数
{
number = num;
state = sta;
eghead = eghed;
vnext = vnxt;
} class Graph //图类
{
private:
int vsize; //记录顶点个数
int esize; //记录边个数
Vertices* vhead; //顶点链表头指针
Vertices* vtail; //顶点链表尾指针
public:
Graph();
~Graph();
void Operate(); //封装操作
private:
Vertices* Revads(const int num); //返回某顶点地址,同时用于检测某顶点是否存在
int Creat(); //创建图
Edge* IfEdge(const int vfrom, const int vto); //查看两顶点间是否存在边
bool Addvt(); //添加顶点
int Addeg(); //添加边
void ShowAll(); //展示全图
int Getweit(const int vfrom, const int vto); //查看指定边权值
bool FinRoad(const int vfrom, const int vto); //查找两点间所有简单路
void Destory(); //销毁图
};
Graph::Graph() //图类构造函数
{
vsize = ;
esize = ;
vhead = NULL;
vtail = NULL;
} Graph::~Graph() //图类析构函数
{
Destory();
}
Vertices* Graph::Revads(const int num) //返回某顶点地址,同时用于检测某顶点是否存在
{
Vertices* pt = vhead; bool flag = false;
while (pt)
{
if (pt->number == num){ flag = true; break; }
pt = pt->vnext;
}
if (flag)return pt;
else return NULL;
} Edge* Graph::IfEdge(const int vfrom, const int vto) //查看两顶点间是否存在边
{
Vertices* pt = Revads(vfrom);
Edge* pte = pt->eghead;
while (pte)
{
if (pte->egnum == vto)
{
return pte;
}
pte = pte->enext;
}
return NULL;
} bool Graph::Addvt() //添加顶点
{
cout << "请您输入要添加顶点的个数,程序将自动从当前图中顶点的最大编号往下顺次为新添加顶点编号:" << endl;
int sum; cin >> sum;
int itnum = vtail->number + ;
int begin = itnum;
for (int i = ; i < sum;i++)
{
vtail->vnext = new Vertices(itnum, NULL, NULL, NULL);
if (!vtail->vnext){ cout << "申请空间失败!" << endl; return false; }
vtail = vtail->vnext;
itnum++;
vsize++;
}
cout << "顶点添加成功!" << endl;
cout << "新顶点编号从" << begin << "到" << itnum- << ",目前图中共有顶点" << vsize << "个。" << endl;
cout << "当前新顶点为孤立顶点,建议您通过选项4添加指向新顶点的边和由新顶点发出的边。" << endl;
return true;
} int Graph::Addeg() //添加边
{
cout << "提示:" << endl;
cout << "输入时,请您依次输入边的起点编号、终点编号和边的权值,中间以空格相隔,例如:1 2 20。并且,请您务必输入正整数,";
cout << "如果您未按规定输入,由此造成的一切后果,将由您个人承担,程序开发者概不负责!" << endl;
bool sign = true, flag = true;
int from, to, weit, choice, abandon,abandon1,abandon2; //标签
Vertices* pt=NULL;
while (sign)
{
while (flag)
{
abandon = ; abandon1 = ; abandon2 = ; //只要重新输入,就要进行一次初始化
cout << "请您依次输入边的起点、终点和权值:" << endl;
cin>> from >> to >> weit;
if (from == to) //如果起、止点相同,不进行进一步检查,直接进行选择
{
cout << "起点编号与终点编号不得相同!重新输入请按1,放弃本次输入请按0:" << endl;
cin >> choice;
if (choice == ){ abandon1 = ; abandon = ; }
else { abandon1 = ; flag = false; }
}
if (!abandon1) //如果起、止点不同,检查起、止点是否正确及两点间是否有边
{
pt = Revads(from);
if (!pt) //如果起点不存在,不进行进一步检查,直接进行选择
{
cout << "您输入的起点不存在!重新输入请按1,放弃本次输入请按0:" << endl;
cin >> choice;
if (choice == ){ abandon2 = ; abandon = ; }
else { abandon2 = ; flag = false; }
}
else //如果起点存在,检查终点,若果终点不存在,不进行进一步检查,直接进行选择
{
if (!Revads(to))
{
cout << "您输入的终点不存在!重新输入请按1,放弃本次输入请按0:" << endl;
cin >> choice;
if (choice == ){ abandon2 = ; abandon = ; }
else { abandon2 = ; flag = false; }
}
}
if (!abandon2)//如果两点输入正确且都存在,检查两点间是否有边,若无,进行选择
{
Edge* ifedge = IfEdge(from, to);
if (ifedge)
{
cout << "从顶点" << from << "到顶点" << to << "的边已经存在,本程序部允许重复添加!重新输入请按1,放弃本次输入请按0:" << endl;
cin >> choice;
if (choice == )abandon = ;
else flag = false;
}
}
}
if (flag)flag = false;
else flag = true;
} //控制输入正确的起点和终点
//插入边
if (!abandon) //如果起点和终点输入正确,开始插入边
{
Edge* pte = new Edge(to, weit, NULL);
if (!pte){ cout << "申请空间失败!" << endl; goto marka; }
if (!pt->eghead)
{
pt->eghead = pte;
}
else
{
Edge* pter = pt->eghead;
while (pter->enext)
pter = pter->enext;
pter->enext = pte;
}
esize++;
cout << "添加成功!目前图中有边" <<esize<< "条。" << endl;
}
cout << "是否继续添加边?是请按1,否则请按0:" << endl;
cin >> choice;
if (choice == )flag = true;
else sign = false;
}
cout << "边添加完毕!目前图中共有边" <<esize<< "条。"<<endl;
marka:
return ;
} int Graph::Creat() //创建图
{
bool sign = false, flag = true;
int choice1;
cout << "请您输入欲创建图的顶点的个数,程序将为您创建顶点并为顶点从1开始顺序编号:" << endl;
cout << "(注意:请您务必输入正整数,否则后果自负!)" << endl;
int numofv; cin >> numofv;
int i;
for (i = ; i <= numofv;i++)
{
if (!vhead)
{
vhead = vtail = new Vertices(i, NULL,NULL, NULL);
if (!vhead){ cout << "申请空间失败!" << endl; goto markc;}
}
else
{
vtail->vnext = new Vertices(i,NULL, NULL, NULL);
if (!vtail->vnext){ cout << "申请空间失败!" << endl; goto markc; }
vtail = vtail->vnext;
}
}
vsize = i - ;
cout << "顶点创建成功!编号从1到" <<vsize<<"。"<< endl;
cout << "是否添加边?是请按1,否则请按0:" << endl;
cin >> choice1;
if (choice1 == )Addeg();
if (choice1 == )cout << "图创建成功,但图中无边!" << endl;
else cout << "图创建成功!" << endl;
markc:
return ;
} void Graph::ShowAll() //展示全图
{
cout << "<>内为顶点编号,[]内为权值:" << endl;
cout << "顶点 " << "相邻顶点及边的权值" << endl;
Vertices* pt = vhead;
while (pt)
{
cout << setiosflags(ios::left);
cout << "<"<<setw()<<pt->number <<">"<< " ";
Edge* pte = pt->eghead;
while (pte)
{
cout << "<" << setw()<<pte->egnum << ">" << "[" <<setw()<< pte->weight << "]" << " ";
pte = pte->enext;
}
cout << endl;
pt = pt->vnext;
}
} int Graph::Getweit(const int vfrom, const int vto) //查看指定边权值
{
Vertices* pt = Revads(vfrom);
Edge* pte = pt->eghead;
while (pte)
{
if (pte->egnum == vto)
return pte->weight;
pte = pte->enext;
}
return ;
} bool Graph::FinRoad(const int vfrom, const int vto) //查找两点间所有简单路
{
bool road = false, right, repeat, goon1, goon2;
Vertices* pt = NULL;
Edge* pte = NULL;
int* array = new int[vsize];
array[] = vfrom;
int top = ;
while (top>=)
{
right = false; repeat = false; goon1 = true; goon2 = true;
pt = Revads(array[top]);
pte = pt->state;
if (!pte)
{
pt->state = pt->eghead; top--; goon1 = false;
}
if (goon1)
{
while (!right&&pte)
{
int item = pte->egnum;
for (int i = ; i <= top;i++)
{
if (array[i] == item)
{
repeat = true;
break;
}
}
if (repeat)
{
repeat = false;
pte = pte->enext;
}
else right = true;
}//内层while结束
if (!pte)
{
pt->state = pt->eghead; top--; goon2 = false;
}
if (goon2)
{
array[++top] = pte->egnum;
pt->state = pte->enext;
if (pte->egnum == vto)
{
road = true;
int sum = ;
for (int i = , j = ; j <= top;i++,j++)
{
sum = sum + Getweit(array[i], array[j]);
}
for (int i = ; i <= top; i++)
{
cout << array[i] << " ";
}
cout << "权值:" << sum;
cout << endl;
top--;
}
}//goon2结束
}//goon1结束
}//外层while结束
delete[]array;
return road;
} void Graph::Destory() //销毁图
{
while (vhead)
{
Edge* pte = vhead->eghead;
while (pte)
{
Edge* iteme = pte;
pte = pte->enext;
delete iteme;
}
Vertices* itemv = vhead;
vhead = vhead->vnext;
delete itemv;
}
vhead = NULL;
vtail = NULL;
vsize = ;
esize = ;
} void Graph::Operate() //封装操作
{
bool flager = true;
while (flager)
{
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;
int chonum; //choice number
cin >> chonum;
switch (chonum)
{
//创建图
case :
{
if (vhead){ cout << "图已经创建,无需再建!若想新建,请您先销毁旧图!" << endl; break; }
Creat();
break;
}
//展示全图
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!无法执行展示全图操作!" << endl; break; }
ShowAll();
break;
}
//添加顶点
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!无法在此处执行添加顶点操作!您可通过选项1来添加顶点。" << endl; break; }
Addvt();
break;
}
//添加边
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!无法执行添加边操作!" << endl; break; }
Addeg();
break;
}
//删除顶点
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!无法执行删除顶点操作!" << endl; break; }
int choice5,ver;
Vertices* pt = NULL;
cout << "警告:" << endl;
cout << "删除顶点操作存在风险!本程序在删除顶点的同时,将自动删除与该顶点直接相连的所有边(包括指向该顶点的和由该顶点发出的),";
cout << "因此,删除顶点操作可能产生较为严重的后果(如使连通的图一分为二或产生孤立点等)。请您慎重考虑!";
cout << "为安全起见,本操作一次只允许删除一个顶点,若您想删除多个顶点,可重复执行本操作。" << endl;
cout << "您确定要删除顶点吗?确定请按1,取消请按0:" << endl;
cin >> choice5;
if (choice5 == )break;
cout << "提示:" << endl;
cout << "输入顶点编号时,请您务必输入正整数,如果您未按规定输入,由此造成的一切后果,将全部由您个人承担,程序开发者概不负责!" << endl;
bool sign5 = true;
while (sign5) //控制输入正确的顶点编号
{
cout << "请您输入顶点编号:" << endl;
cin >> ver;
pt = Revads(ver);
if (!pt)
{
cout << "您输入的顶点在当前图中不存在!重新输入请按1,退出删除顶点操作请按0:" << endl;
cin >> choice5;
if (choice5 == )goto mark5;
else sign5 = false;
}
if (sign5)sign5 = false;
else sign5 = true;
}//while(sign5)结束
//删除
//将欲删除顶点及其边单拿出来
if (pt == vhead)
vhead = vhead->vnext;
else
{
Vertices* ptv = vhead;
while (ptv) //找到pt的前驱
{
if (ptv->vnext == pt)
break;
ptv = ptv->vnext;
}
ptv->vnext = pt->vnext;
}
//删除顶点指向的边
Edge* pte = pt->eghead;
while (pte)
{
Edge* iteme = pte;
pte = pte->enext;
delete iteme;
esize--;
}
//删除顶点
delete pt;
vsize--;
//删除指向该顶点的边
Vertices* ptrv = vhead;
while (ptrv)
{
int item = ptrv->number;
Edge* ptre = IfEdge(item, ver);
if (ptre)
{
if (ptre==ptrv->eghead)
{
ptrv->eghead = ptre->enext;
delete ptre;
esize--;
}
else
{
Edge* pre = ptrv->eghead;
while (pre)
{
if (pre->enext == ptre)
break;
pre = pre->enext;
}
pre->enext = ptre->enext;
delete ptre;
esize--;
}
}
ptrv = ptrv->vnext;
}//while(ptrv)结束
cout << "删除成功!目前图中共有顶点" << vsize << "个,边" << esize << "条。" << endl;
mark5:
break;
}
//删除边
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!无法执行删除边操作!" << endl; break; }
int choice6,from,to;
Vertices* pt=NULL;
Edge* ifedge=NULL;
cout << "警告:" << endl;
cout << "删除边操作存在风险!(如使连通的图一分为二或产生孤立点等)请您慎重考虑!为安全起见,本操作一次只允许删除一条边,";
cout << "若您想删除多条边,可重复执行本操作。" << endl;
cout << "您确定要删除边吗?确定请按1,取消请按0:" << endl;
cin >> choice6;
if (choice6 == )break;
cout << "提示:" << endl;
cout << "输入时,请您依次输入起点编号和终点编号,务必输入正整数,并以空格相隔,例如:1 2。如果您未按规定输入,";
cout << "由此造成的一切后果,将全部由您个人承担,程序开发者概不负责!" << endl;
bool flag6=true,control6,control61;
while (flag6)
{
control6 = true; control61 = true;
cout << "请您依次输入边的起点编号和终点编号:" << endl;
cin >> from >> to;
if (from == to)
{
cout << "起点编号与终点编号不得相同!重新输入请按1,退出删除操作请按0:" << endl;
cin >> choice6;
if (choice6 == )goto mark6;
else { control6 = false; flag6 = false; }
}
if (control6)
{
pt = Revads(from);
if (!pt)
{
cout << "您输入的起点不存在!重新输入请按1,退出删除操作请按0:" << endl;
cin >> choice6;
if (choice6 == )goto mark6;
else { control61 = false; flag6 = false; }
}
else
{
if (!Revads(to))
{
cout << "您输入的终点不存在!重新输入请按1,退出删除操作请按0:" << endl;
cin >> choice6;
if (choice6 == )goto mark6;
else { control61 = false; flag6 = false; }
}
}
if (control61)
{
ifedge = IfEdge(from, to);
if (!ifedge)
{
cout << "不存在从顶点" << from << "到顶点" << to << "的边,无法执行删除操作!重新输入请按1,退出删除操作请按0:" << endl;
cin >> choice6;
if (choice6 == )goto mark6;
else flag6 = false;
}
}
}
if (flag6)flag6 = false;
else flag6 = true;
} //控制输入正确的起点和终点
//删除
if (ifedge==pt->eghead)
{
Edge* item = ifedge;
ifedge = ifedge->enext;
pt->eghead = ifedge;
delete item;
}
else
{
Edge* pter = pt->eghead;
while (pter)
{
if (pter->enext = ifedge)
break;
}
pter->enext = ifedge->enext;
delete ifedge;
}
esize--; //边数减1
cout << "从顶点" << from << "到顶点" << to << "的边已成功删除!目前图中共有边" <<esize<<"条。"<< endl;
mark6:
break;
}
//查看指定边权值
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!无法执行查询操作!" << endl; break; }
cout << "提示:" << endl;
cout << "输入时,请您依次输入起点编号和终点编号,务必输入正整数,并以空格相隔,例如:1 2。如果您未按规定输入,";
cout << "由此造成的一切后果,将全部由您个人承担,程序开发者概不负责!" << endl;
bool control = true,sign7=true,flag7,flag71;
int vf, vt, choice7;
Vertices* ptv = NULL;
Edge* ifedge = NULL;
while (sign7)
{
while (control) //控制输入正确的起点编号和终点编号
{
flag7 = true; flag71 = true;
cout << "请您依次输入起点编号和终点编号:" << endl;
cin >> vf >> vt;
if (vf == vt)
{
cout << "起点编号与终点编号不得相同!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice7;
if (choice7 == )goto mark7;
else { flag7 = false; control = false; }
}
if (flag7)
{
ptv = Revads(vf);
if (!ptv)
{
cout << "您输入的起点编号在当前图中不存在!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice7;
if (choice7 == )goto mark7;
else { flag71 = false; control = false; }
}
else
{
if (!Revads(vt))
{
cout << "您输入的终点编号在当前图中不存在!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice7;
if (choice7 == )goto mark7;
else { flag71 = false; control = false; }
}
}
if (flag71)
{
ifedge = IfEdge(vf, vt);
if (!ifedge)
{
cout << "不存在从顶点" << vf << "到顶点" << vt << "的边,无法执行查找操作!重新输入请按1,退出删除操作请按0:" << endl;
cin >> choice7;
if (choice7 == )goto mark7;
else control = false;
}
}
}
if (control)control = false;
else control = true;
}//while循环结束
int itemw = ifedge->weight;
cout << "从顶点" << vf << "到顶点" << vt << "的边的权值为" << itemw << endl;
cout << "是否继续查询?是请按1,否则请按0:" << endl;
cin >> choice7;
if (choice7 == )sign7 = false;
else control = true;
}
mark7:
break;
}
//修改指定边权值
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!无法执行修改操作!" << endl; break; }
cout << "提示:" << endl;
cout << "输入时,请您依次输入要修改权值的边的起点编号和终点编号,务必输入正整数,并以空格相隔,例如:1 2。如果您未按规定输入,";
cout << "由此造成的一切后果,将全部由您个人承担,程序开发者概不负责!" << endl;
bool control = true, sign8 = true,flag8,flag81;
int vf, vt, choice8;
Vertices* ptv = NULL;
Edge* ifedge = NULL;
while (sign8)
{
while (control) //控制输入正确的起点编号和终点编号
{
flag8 = true; flag81 = true;
cout << "请您依次输入起点编号和终点编号:" << endl;
cin >> vf >> vt;
if (vf == vt)
{
cout << "起点编号与终点编号不得相同!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice8;
if (choice8 == )goto mark8;
else { flag8 = false; control = false; }
}
if (flag8)
{
ptv = Revads(vf);
if (!ptv)
{
cout << "您输入的起点编号在当前图中不存在!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice8;
if (choice8 == )goto mark8;
else { flag81 = false; control = false; }
}
else
{
if (!Revads(vt))
{
cout << "您输入的终点编号在当前图中不存在!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice8;
if (choice8 == )goto mark8;
else { flag81 = false; control = false; }
}
}
if (flag81)
{
ifedge = IfEdge(vf, vt);
if (!ifedge)
{
cout << "不存在从顶点" << vf << "到顶点" << vt << "的边,无法执行查找操作!重新输入请按1,退出删除操作请按0:" << endl;
cin >> choice8;
if (choice8 == )goto mark8;
else control = false;
}
}
}
if (control)control = false;
else control = true;
}//while循环结束
cout << "请您输入新权值(务必输入正整数,否则后果自负!):" << endl;
int oldwt,newwt; cin >> newwt;
oldwt = ifedge->weight;
ifedge->weight = newwt;
cout << "修改成功!" << endl;
cout << "该边权值从" << oldwt << "修改为" << newwt << "。" << endl;
cout << "是否继续修改?是请按1,否则请按0:" << endl;
cin >> choice8;
if (choice8 == )sign8 = false;
else control = true;
}
mark8:
break;
}
//查找两点间所有简单路
case :
{
cout << "提示:" << endl;
cout << "输入时,请您依次输入起点编号和终点编号,务必输入正整数,并以空格相隔,例如:1 2。如果您未按规定输入," ;
cout << "由此造成的一切后果,将全部由您个人承担,程序开发者概不负责!" << endl;
bool control=true,flag9;
int vf, vt,choice9;
Vertices* ptv = NULL;
while (control) //控制输入正确的起点编号和终点编号
{
flag9 = true;
cout << "请您依次输入起点编号和终点编号:" << endl;
cin >> vf >> vt;
if (vf == vt)
{
cout << "起点编号与终点编号不得相同!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice9;
if (choice9 == )goto mark9;
else { flag9 = false; control = false; }
}
if (flag9)
{
ptv = Revads(vf);
if (!ptv)
{
cout << "您输入的起点编号在当前图中不存在!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice9;
if (choice9 == )goto mark9;
else control = false;
}
else
{
if (!Revads(vt))
{
cout << "您输入的终点编号在当前图中不存在!重新输入请按1,退出查找操作请按0:" << endl;
cin >> choice9;
if (choice9 == )goto mark9;
else control = false;
}
}
}
if (control)control = false;
else control = true;
}//while循环结束
//顶点状态初始化
Vertices* ptr = vhead;
while (ptr)
{
ptr->state = ptr->eghead;
ptr = ptr->vnext;
}//初始化完成
bool ifroad = FinRoad(vf, vt); //执行查找函数
if (ifroad)
{
cout << "以上为从" << vf << "到" << vt << "的所有简单路及路径对应权值!" << endl;
}
else cout << "不存在从" <<vf<<"到"<<vt<<"的任何简单路!"<< endl;
//状态还原
Vertices* ptrv = vhead;
while (ptrv)
{
ptrv->state = NULL;
ptrv = ptrv->vnext;
}//还原完成
mark9:
break;
}
//销毁图
case :
{
if (!vhead){ cout << "图还未创建或已被销毁!不能再销毁!" << endl; break; }
cout << "您确定销毁该图吗?确定请按1,取消请按0:" << endl;
int choice10; cin >> choice10;
if (choice10 == )
Destory();
cout << "图已销毁!" << endl;
break;
}
//处理用户错误输入
default:
{
cout << "您的输入有误,无法进行操作!" << endl;
break;
}
}//switch结束
//循环控制
cout << "是否继续?继续请按1,退出请按0:" << endl;
int ifgoon;
cin >> ifgoon;
if (ifgoon == )flager = false;
}//while结束
} #endif
//.cpp文件
#include<iostream>
#include"graph.h"
using namespace std; int main()
{
//是否进入程序
int uscho; bool flag = true;//uscho:user choice的缩写
cout << "敬告;请您务必按提示要求操作,如果您进行了规定以外的操作,由此造成的一切后果,将全部由您个人承担,程序开发者概不负责!" << endl;
cout << "是否进入程序?进入请按1,否则按0;" << endl;
cin >> uscho;
if (uscho == ) return ;
Graph graph;
graph.Operate();
return ;
} Ⅵ.结语
代码已经过测试,在VS2013上成功运行!
发此文有两大目的:
.和大家交流经验,供需要的人参考。
.在下菜鸟,代码中难免有不妥之处,恳求大神批评指正。您的批评就是在下提高
的起点,对于您的批评,在下将不胜感激!
C++实现有向权图的基本操作,界面友好,操作方便,运行流畅的更多相关文章
- 带权图的最短路径算法(Dijkstra)实现
一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...
- Java数据结构——带权图
带权图的最小生成树--Prim算法和Kruskal算法 带权图的最短路径算法--Dijkstra算法 package graph; // path.java // demonstrates short ...
- Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离
Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离,既不是DFS搜索,也不是BFS搜索. 把Dijkstra 算法应用于无权图,或者所有边的权都相等的图,Dijkstra 算法等同于 ...
- 无向带权图的最小生成树算法——Prim及Kruskal算法思路
边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以 ...
- C语言——无向带权图邻接矩阵的建立
#include <stdio.h> #include "Graph.h" #define MAX_INT 32767 /* #define vnum 20 #defi ...
- BZOJ3438:小M的作物 (最大闭合权图->最小割)
小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子 有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可以获得ai ...
- java数据结构----带权图
1.带权图:要引入带权图,首先要引入最小生成树,当所有的边拥有相同的权值时.问题变得简单了,算法可以选择任意一条边加入最小生成树.但是当边有不同的权值时,需要用一些算法决策来选择正确的边. 2.带权图 ...
- Dijkstra含权图最短路径;审判,不要错过枚举退款保证不会重复;国际象棋八皇后问题
求两节点的最短通路.对于无权图,能够通过图的广度优先遍历求解.含权图一般通过Dijkstra算法求解. import java.util.ArrayList; import java.util.Has ...
- python文件(概念、基本操作、常用操作、文本文件的编码方式)
文件 目标 文件的概念 文件的基本操作 文件/文件夹的常用操作 文本文件的编码方式 01. 文件的概念 1.1 文件的概念和作用 计算机的 文件,就是存储在某种 长期储存设备 上的一段 数据 长期存储 ...
随机推荐
- java web sql注入测试(3)---现象分析
那为什么出现以上问题呢?这是程序代码层控制不当导致的.如果web前端对输入数据控制严格,会对数据库进行操作的字符串,在客户端做敏感字符转义处理,或者在操作数据库的dao层,使用动态参数的sql,不使用 ...
- 雅虎工程师提供的CSS初始化代码
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,b ...
- Broadwell I7-5775c/5675c BSOD 蓝屏问题
今年6月末Intel发布了第五代台式机CPU,代号Broadwell,跳票一年多,仅有两款零售型号,I7-5775C和I5-5675C. 第一时间就买来试用,当时还是在日亚购买的,等待了10天左右终于 ...
- VS2010 断点无效肿么办?
[1]分析原理: 1. 断点无效是因为目标文件和源文件的更新时间不一致, 编译器不认为当前的源文件是目标文件的当前版本. 2. IDE不会关心源文件的编码格式,能读入即可, 另存为Unicode或AS ...
- AC68U 内Linux 终端前后的切换,终端挂起和恢复
ssh 登录终端后, 如果想切换到本地上来, 可以按: -,Ctrl+Z 如果要恢复到远程端,则命令: fg
- 如何通过ps -ef|grep tomcat只获得你需要的查询进程,排除掉grep本身的进程信息
执行命令:ps -ef|grep tomcat|grep /opt/upay3/application/dispatcherTomcat/bin输出的进程信息会显示2个:包括grep本身的进程+你查询 ...
- (转载)PERL 处理CSV
#!/usr/bin/perl#use strict;open(FILE1,"C:/Perl/BX/BX-Users.csv");open(FILE2,"C:/Perl/ ...
- struts2,实现Ajax异步通信
用例需要依赖的jar: struts2-core.jar struts2-convention-plugin.jar,非必须 org.codehaus.jackson.jar,提供json支持 用例代 ...
- Entrust是一种为Laravel5添加基于角色的权限的简洁而灵活的方法。
安装 首先要在composer.json中添加: "zizaco/entrust": "5.2.x-dev" 然后运行composer install 或者 c ...
- mybatis中#{}和${}的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111&qu ...