问题描述 :
目的:使用C++模板设计并逐步完善图的邻接矩阵抽象数据类型(ADT)。
内容:请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接矩阵ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。)
解题
把adt全写完了再做后面的题
注意他给的模板要传的参数有一个指向指针的指针
构造起来很麻烦。。下面main函数给了构造例子你们可以参考一下
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
#define Status int
template <class TypeOfVer, class TypeOfEdge>
class adjmatrix_graph {
private:
int Vers; //顶点数
int Edges; //边数
TypeOfEdge** edge; //存放邻接矩阵(TypeOfEdge表示顶点关系类型。对于无权图,用1或0,表示相邻否;对于带权图,则为权值类型)
TypeOfVer* ver; //存放结点值
TypeOfEdge noEdge; //邻接矩阵中的∞的表示值
string GraphKind; //图的种类标志
bool DFS(int u, int& num, int visited[]) //DFS遍历(递归部分)
{
visited[u] = 1;
num++;
if (num != 1)
cout << "->" << ver[u];
else
cout << ver[u];
for (int i = 0; i < Vers; i++)
if (edge[u][i] != noEdge && visited[i] == 0)
DFS(i,num,visited); //如果满足条件,就从该顶点开始再次进行DFS操作
return 1;
}
public:
void display()//测试用
{
for (int i = 0; i < Vers; i++) {
cout << ver[i] ;
if (i != Vers - 1)
cout << " ";
}
cout <<endl<< endl;
for (int i = 0; i < Vers; i++) {
for (int k = 0; k < Vers; k++)
cout << edge[i][k] << " ";
if (i!=Vers-1)
cout << endl;
}
}
adjmatrix_graph(const string& kd, int vSize, const TypeOfVer d[], const TypeOfEdge noEdgeFlag)
{//构造函数构造一个只有结点没有边的图。4个参数的含义:图的类型、结点数、结点值和邻接矩阵中表示结点间没有边的标记(无权图:0,有权图:输入参数定)
GraphKind = kd; noEdge = noEdgeFlag;
Vers = vSize; Edges = 0;
ver = new TypeOfVer[vSize];
for (int i = 0; i < Vers; i++)
ver[i] = d[i];
edge = new TypeOfVer* [vSize];
for (int i = 0; i < Vers; i++) {
edge[i] = new TypeOfVer[vSize];
for (int k = 0; k < Vers; k++)
edge[i][k] = noEdge;
}
}
adjmatrix_graph(const string& kd, int vSize, int eSize, const TypeOfVer d[], int** e)//图
{//构造函数构造一个无权图。5个参数的含义:图的类型、结点数、边数、结点集和边集
GraphKind = kd; noEdge = 0;
Vers = vSize; Edges = eSize;
ver = new TypeOfVer[vSize];
for (int i = 0; i < vSize; i++)
ver[i] = d[i];
edge = new TypeOfEdge * [vSize];
for (int i = 0; i < vSize; i++) {
edge[i] = new TypeOfEdge[vSize];
}
for (int i = 0; i < vSize; i++)
for (int k = 0; k < vSize; k++)
edge[i][k] = 0;
if (kd=="DG")//有向图
for (int i = 0; i < eSize; i++) {
edge[e[i][0]][e[i][1]] = 1;
}
else
for (int i = 0; i < eSize; i++) {
edge[e[i][0]][e[i][1]] = 1;
edge[e[i][1]][e[i][0]] = 1;
}
}
adjmatrix_graph(const string& kd, int vSize, int eSize, const TypeOfEdge noEdgeFlag, const TypeOfVer d[], int** e, const TypeOfEdge w[])//网
{ //构造函数构造一个有权图。7个参数的含义:图的类型、结点数、边数、无边标记、结点集、边集、权集
GraphKind = kd; noEdge = noEdgeFlag;
Vers = vSize; Edges = eSize;
ver = new TypeOfVer[vSize];
for (int i = 0; i < vSize; i++)
ver[i] = d[i];
edge = new TypeOfVer * [vSize];
for (int i = 0; i < vSize; i++) {
edge[i] = new TypeOfVer[vSize];
}
for (int i = 0; i < vSize; i++)
for (int k = 0; k < vSize; k++)
edge[i][k] = noEdge;
if (kd == "DN")//有向网
for (int i = 0; i < eSize; i++) {
edge[e[i][0]][e[i][1]] = w[i];
}
else
for (int i = 0; i < eSize; i++) {
edge[e[i][0]][e[i][1]] = w[i];
edge[e[i][1]][e[i][0]] = w[i];
}
}
bool GraphisEmpty() { return Vers == 0; } //判断图空否
string GetGraphKind() { return GraphKind; }
bool GetVer(int u, TypeOfVer& data)
{//取得G中指定顶点的值
data = ver[u];
return 1;
}
int GetFirstAdjVex(int u, int& v)
{ //返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
if (u<0 || u>Vers - 1) {
v = -1;
return -1;
}
for (int i = 0; i < Vers; i++)
if (edge[u][i] != noEdge) {
v = i;
return 1;
}
v = -1;
return -1;
}
int GetNextAdjVex(int u, int v, int& w)
{//返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
if (u<0 || u>Vers - 1) {
v = -1;
return -1;
}
for (int i = v; i < Vers; i++)
if (edge[u][i] != noEdge) {
w = i;
return 1;
}
v = -1;
return -1;
}
bool PutVer(int u, TypeOfVer data)
{ //对G中指定顶点赋值
ver[u]=data;
return 1;
}
bool InsertVer(const TypeOfVer& data)
{ //往G中添加一个顶点
TypeOfVer* new_ver = new TypeOfVer[Vers + 1];
memcpy(new_ver, ver, Vers);
new_ver[Vers] = data;
delete[] ver;
ver = new_ver;
TypeOfEdge** new_edge = new TypeOfEdge * [Vers + 1];
for (int i = 0; i <= Vers; i++) {
new_edge[i] = new TypeOfEdge[Vers + 1];
}for (int i = 0; i <= Vers; i++) {
for (int j = 0; j <= Vers; j++) {
if (i == Vers || j == Vers) new_edge[i][j] = 0;
else new_edge[i][j] = edge[i][j];
}
}
for (int i = 0; i < Vers; i++) delete[]edge[i];
delete[] edge;
edge = new_edge;
Vers++;
return true;
}
int LocateVer(TypeOfVer data)
{ //返回G中指定顶点的位置
for (int i = 0; i < Vers; i++) {
if (ver[i] == data)
return i;
}
return -1;
}
bool PrintMatrix()
{ //输出邻接矩阵
for (int i = 0; i < Vers; i++) {
for (int k = 0; k < Vers; k++)
cout << edge[i][k] << " ";
if (i!=Vers-1)
cout << endl;
}
return 1;
}
bool PrintVer()
{//输出结点集
for (int i = 0; i < Vers; i++) {
cout << ver[i];
if (i != Vers - 1)
cout << " ";
}
return 1;
}
int GetVerNum() { return Vers; } //取得当前顶点数
int GetEdgeNum() { return Edges; } //取得当前边数
bool Insert_Edge(int u, int v)
{ //无权图插入一条边
if (u < 0 || v < 0 || u >= Vers || v >= Vers)
return false;
if (GraphKind == "UDG") {
if (edge[u][v] || edge[v][u])
return false;
edge[u][v] = edge[v][u] = 1;
Edges++;
}
else if (GraphKind == "DG") {
if (edge[u][v])
return false;
edge[u][v] = 1;
Edges++;
}
return 1;
}
bool Insert_Edge(int u, int v, TypeOfEdge w)
{ //有权图插入一条边
if (u < 0 || v < 0 || u >= Vers || v >= Vers)
return false;
if (GraphKind == "UDN") {
if (edge[u][v]!=noEdge&& edge[v][u]!=noEdge)
return false;
edge[u][v] = edge[v][u] = w;
Edges++;
}
else if (GraphKind == "DN") {
if (edge[u][v]!=noEdge)
return false;
edge[u][v] = w;
Edges++;
}
return 1;
}
bool DeleteVer(const TypeOfVer& data)
{ //往G中删除一个顶点
int i = LocateVer(data);
if (i == -1) return false;
for (int j = 0; j < Vers; j++) {
if (edge[j]) Edges--;
}
for (int j = i + 1; j < Vers; j++) {
ver[j - 1] = ver[j];
for (int k = 0; k < Vers; k++) {
edge[j - 1][k] = edge[j][k];
}
for (int k = 0; k < Vers; k++) {
edge[k][j - 1] = edge[k][j];
}
}
Vers--;//实际上没删数组空间
return 1;
}
bool Delete_Edge(int u, int v)
{ //无权图删除一条边
if (u < 0 || v < 0 || u >= Vers || v >= Vers)
return false;
if (GraphKind == "UDG") {
if (edge[u][v]==0 && edge[v][u]==0)
return false;
if (edge[u][v] != 0 && edge[v][u] != 0) Edges++;//为下面减两次做铺垫
if (edge[u][v] != 0) {
edge[u][v] = 0;
Edges--;
}
if (edge[v][u] != 0) {
edge[v][u] = 0;
Edges--;
}
}
else if (GraphKind == "DG") {
if (edge[u][v]==0)
return false;
edge[u][v] = 0;
Edges--;
}
return 1;
}
bool Delete_Edge(int u, int v, TypeOfEdge w)
{ //有权图删除一条边
if (u < 0 || v < 0 || u >= Vers || v >= Vers)
return false;
if (GraphKind == "UDN") {
if (edge[u][v] == noEdge && edge[v][u] == noEdge)
return false;
if (edge[u][v] != noEdge && edge[v][u] != noEdge) Edges++;//为下面减两次做铺垫
if (edge[u][v] != noEdge) {
edge[u][v] = noEdge;
Edges--;
}
if (edge[v][u] != noEdge) {
edge[v][u] = noEdge;
Edges--;
}
}
else if (GraphKind == "DN") {
if (edge[u][v] == noEdge)
return false;
edge[u][v] = noEdge;
Edges--;
}
return 1;
}
~adjmatrix_graph()
{ //析构函数
delete[] ver;
for (int i = 0; i < Vers; i++)
delete[]edge[i];
delete[] edge;
}
void DFS_Traverse(int u) //DFS遍历(外壳部分)
{
int num = 0, i = 0;
int visited[1000] = { 0 };
for (i = u; i < Vers; i++) {
if (num == Vers)
return;
if (visited[i] == 0)//如果当前顶点处于未被访问的状态,就对该顶点进行DFS操作
//DFS函数是对当前传入的顶点以及它的未被遍历过的邻接点进行递归遍历输出操作
//当当前顶点和邻接点都被遍历完成后,弧退出DFS函数,进入当前for循环
//这里的for循环相当于对每一个顶点都进行判断,看其是否被遍历过,防止漏网之鱼
DFS(i, num, visited);
}
return;
}
void BFS_Traverse(int u)
{ //BFS遍历
bool vis[1000] = { 0 };
int f = 0;
queue<int> q;
q.push(u);
vis[u] = 1;
while (!q.empty()) {
int x = q.front();
for (int i = 0; i < Vers; i++) {
if (!vis[i] && edge[x][i] != 0) {
q.push(i);
vis[i] = 1;
}
}q.pop();
if (f) cout << "->"; f = 1;
cout << ver[x];
}
}
bool ExistEdge(int u, int v) //检查指定2个顶点是否是邻接顶点
{
if (u < 0 || v < 0 || u >= Vers || v >= Vers) return false;
if (edge[u][v] || edge[v][u]) return true;
return 0;
}
};
int main()
{
string str;
cin >> str;
int Vers = 0, i = 0, k = 0;
cin >> Vers;
int ver[1000] = { 0 }, noedge = 0;
for (; i < Vers; i++)
cin >> ver[i];
cin >> noedge;
int edge = 0; cin >> edge;
int edges[1000][2] = { 0 };
for (i = 0; i < edge; i++)
for (k = 0; k < 2; k++)
cin >> edges[i][k];
int** Edge;
int* EDge[100];
for (i = 0; i < edge; i++)
EDge[i] = edges[i];
Edge = EDge;
int w[1000] = { 0 };
for (i = 0; i < edge; i++)
cin >> w[i];
adjmatrix_graph<int,int> G(str, Vers, edge, noedge, ver, Edge, w);
G.display();
G.BFS_Traverse(1);
return 0;
}