赞
踩
目的:使用C++模板设计并逐步完善图的邻接矩阵抽象数据类型(ADT)。
内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接矩阵ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。)
(2)设计并实现一个算法,基于广度优先搜索的思想,对于给定的有向图(网),实现拓扑排序。如排序成功,返回true;否则返回false。无论排序是否成功,都请给出最终的排序结果。图的存储结构采用邻接矩阵。将其加入到ADT中。
注意:DG(有向图), DN(有向网), UDG(无向图), UDN(无向网)
参考函数原型:
(1)重载形式1
//拓扑排序(仅提供拓扑排序是否成功)
template<class TypeOfVer, class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer, TypeOfEdge>::TopSort();
(2)重载形式2
//拓扑排序(不仅提供拓扑排序是否成功,排序序列存储在引用参数topsort[]中)
template<class TypeOfVer, class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer, TypeOfEdge>::TopSort(int &num, int topsort[]);
建图的输入数据格式参见建图的算法说明。(以有向图为例,调用重载形式2的函数)
第一行:图的类型
第二行:结点数
第三行:结点集
第四行:边数
第五行:边集
第一行:顶点集
空行
第二行:邻接表
空行
第三行:拓扑排序结果
第四行:true(排序成功)/false(排序失败)
DG
8
A B C D E F G H
10
0 2
0 6
1 6
1 7
2 3
3 4
3 6
5 4
6 5
7 5
A B C D E F G H
0 0 1 0 0 0 1 0
0 0 0 0 0 0 1 1
0 0 0 1 0 0 0 0
0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0
A->B->C->H->D->G->F->E
true
拓扑排序的方法:
/*
描述:拓扑排序(不仅提供拓扑排序是否成功,排序序列存储在引用参数topsort[]中)
参数:num是拓扑序列中的点的个数
topsort是保存拓扑序列的数组
*/
bool TopSort(int &num, int topsort[]){
//如果是无向图直接输出
if(GraphKind == "UDG" || GraphKind == "UDN") return false;
//生成表示各个结点度的数组,并初始化
int degree[Vers]={0} ;
//统计各个顶点的度
for(int i = 0;i < Vers;i ++)
{
for(int j = 0;j < Vers;j ++)
{
if(edge[i][j] != noEdge){
degree[j] ++;
}
}
}
//生成用于遍历数组的度
SqQueue<int> temp;
//遍历整个数组,找度为0的点入队
for(int i = 0;i < Vers;i ++)
{
if(degree[i] == 0){
temp.enQueue(i);
degree[i] = -1;
}
}
//开始遍历
int mid,j = 0; //临时值,用来保存出队的点
while(!temp.QueueisEmpty()){
//出队
temp.deQueue(mid);
topsort[j] = mid;
j ++;
num ++;
//遍历对应的矩阵列,将对应的度数都减去
for(int i = 0; i < Vers; i ++) {
if(edge[mid][i] != noEdge) {
degree[i] --;
if(degree[i] == 0) {
temp.enQueue(i);
degree[i] = -1;
}
}
}
}
//遍历完比,就检查是否还有大于零的项
if(num<Vers) {
return false;
}
return true;
}
我觉得吧,我还是看样例吧
这就有点懵了
int main() {
//设定图的类型
string gk;
getline(cin,gk);
//设定结点的个数
int vertexNum = 0;
cin>>vertexNum;
//获取对应的结点值
string vertex[vertexNum];
for(int i = 0;i < vertexNum;i ++)
{
cin>>vertex[i];
}
//获取终结标志
int noEdgeFlag=0;
if(gk == "DN" || gk == "UDN") {
cin>>noEdgeFlag;
}
//获取边的数量
int edgeNum;
cin>>edgeNum;
//获取边的位置
int *edge[edgeNum];
for(int i = 0; i< edgeNum;i ++){
edge[i] = new int[2];
}
for(int i = 0;i < edgeNum;i ++)
{
cin>>edge[i][0];
cin>>edge[i][1];
}
int weight[edgeNum];
if(gk == "DN" || gk == "UDN") {
//获取权值数组
for(int i = 0; i < edgeNum; i ++) {
cin>>weight[i];
}
}
int num = 0;
int sortNum[vertexNum];
bool flag = true;
if(gk == "DG" || gk == "UDG") {
//无向图的创建
adjmatrix_graph<string,int> test1(gk,vertexNum,edgeNum,vertex,edge);
test1.print_vertex();
cout<<endl;
test1.PrintMatrix();
cout<<endl;
flag = test1.TopSort(num,sortNum);
if(flag) {
cout<<"true";
} else {
cout<<"false";
}
} else {
//创建有向权值图
adjmatrix_graph<string,int> test2(gk,vertexNum,edgeNum,noEdgeFlag,vertex,edge,weight);
test2.print_vertex();
cout<<endl;
test2.PrintMatrix();
cout<<endl;
flag = test2.TopSort(num,sortNum);
if(flag) {
cout<<"true";
} else {
cout<<"false";
}
}
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。