#include<iostream>
using namespace std;
#define MaxInt 32767
#define MVNum 100
int i,j,k;
typedef struct
{
char vexs[MVNum];//顶点表
int arcs[MVNum][MVNum];//邻接矩阵
int vexnum,arcnum;//图当前的点数和边数
}AMGraph;
void InitUDN(AMGraph &G)//初始化无向图邻接矩阵
{
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
G.arcs[i][j]=0;
}
}
}
void InitDN(AMGraph &G)//初始化有向图邻接矩阵
{
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
G.arcs[i][j]=MaxInt;
}
}
}
void CreateUDN(AMGraph &G)//构造无向图的邻接矩阵
{
char n,m;
cout<<"依次输入有边的两个顶点(例如 a b)"<<endl;
for(k=0;k<G.arcnum;k++){
cin>>n>>m;
cout<<n<<"-"<<m<<endl;
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
if(G.vexs[j]==m&&G.vexs[i]==n){
G.arcs[i][j]=1;
G.arcs[j][i]=1;}
}
}
}
}
void CreateDN(AMGraph &G)//构造有向图的邻接矩阵
{
cout<<"依次输入有向边的头和尾(例如 a b)"<<endl;
char n,m;
for(k=0;k<G.arcnum;k++){
cin>>n>>m;
cout<<n<<"->"<<m<<endl;
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
if(G.vexs[j]==m&&G.vexs[i]==n){
G.arcs[i][j]=1;
}
}
}
}
}
void PrintAMGraph(AMGraph G)//输出图
{
cout<<"G邻接矩阵为"<<endl;
cout<<" ";
for(i=0;i<G.vexnum;i++)
cout<<G.vexs[i]<<" ";
cout<<endl;
for(i=0;i<G.vexnum;i++)
{
cout<<G.vexs[i]<<" ";
for(j=0;j<G.vexnum;j++)
{
cout<<G.arcs[i][j]<<" ";
}
cout<<endl;
}
}
bool visited[MVNum];
void DFS_AM(AMGraph G,int v)//从顶点v出发深度优先遍历
{
cout<<G.vexs[v];visited[v]=true;
for(int w=0;w<G.vexnum;w++)
{
if(G.arcs[v][w]!=0&&(!visited[w]))
DFS_AM(G,w);
}
}
void CalculateDN(AMGraph G)//计算有向图每个顶点的出度和入度
{
for(i=0;i<G.vexnum;i++)
{
cout<<G.vexs[i]<<"的出度为:";
int sum=0;
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[i][j]==1)sum=sum+1;
}
cout<<sum<<"的入度为:";
sum=0;
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[j][i]==1)sum=sum+1;
}
cout<<sum<<endl;
}
}
void CalculateUDN(AMGraph G)//计算无向图每个顶点的度
{
for(i=0;i<G.vexnum;i++)
{
cout<<G.vexs[i]<<"的度为:";
int sum=0;
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[i][j]==1)sum=sum+1;
}
cout<<sum<<endl;
}
}
void AM()//建立一个验证操作实现的函数进行测试
{
AMGraph G;
cout<<"输入总顶点数,边数(例如5 6)"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"依次输入点的信息"<<endl;
for(i=0;i<G.vexnum;i++)
cin>>G.vexs[i];
cout<<"输入数字选择创建 1有向图 还是 2无向图"<<endl;
int Graph;
cin>>Graph;
switch(Graph)
{
case 1:InitDN(G);CreateDN(G);break;
case 2:InitUDN(G);CreateUDN(G);break;
}
PrintAMGraph(G);
cout<<"从"<<G.vexs[0]<<"开始深度优先遍历"<<endl;
DFS_AM(G,0);//深度优先遍历
cout<<endl;
switch(Graph)
{
case 1:CalculateDN(G);break;
case 2:CalculateUDN(G);break;
}
}
typedef struct ArcNode//边表
{
int adjvex;
struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode//顶点表
{
char data;
ArcNode *firstarc;
}VNode,AdjList[MVNum];//
typedef struct
{
AdjList vertices;
int vexnum,arcnum;//图当前的顶点数和边数
}ALGraph;
int LocateVex(ALGraph G,char x)//查找顶点值为X的下标
{
for(int a=0;a<G.vexnum;a++)
{
if(G.vertices[a].data==x)return a;
}
return 0;
}
void createUDG(ALGraph &G)//邻接表法,创建无向图
{
ArcNode *p;
cout<<"输入总顶点数,边数(例如5 6)"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"依次输入点的信息(例如a b c d e)"<<endl;
for(i=0;i<G.vexnum;i++)//顶点表
{
cin>>G.vertices[i].data;
G.vertices[i].firstarc=0;
}
cout<<"依次输入有边的两个顶点(例如 a b)"<<endl;
for(k=0;k<G.arcnum;k++)//边表
{
char n,m;
cin>>n>>m;
i=LocateVex(G,n);
j=LocateVex(G,m);
p=new ArcNode;
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
p=new ArcNode;
p->adjvex=i;
p->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p;
cout<<n<<"-"<<m<<endl;
}
}
void createDG(ALGraph &G)//邻接表法,创建有向图
{
ArcNode *p;
cout<<"输入总顶点数,边数(例如5 6)"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<"依次输入点的信息(例如a b c e d)"<<endl;
for(i=0;i<G.vexnum;i++)//顶点表
{
cin>>G.vertices[i].data;
G.vertices[i].firstarc=NULL;
}
cout<<"依次输入有向边的头和尾(例如 a b)"<<endl;
for(k=0;k<G.arcnum;k++)//边表
{
char n,m;
cin>>n>>m;
int i=LocateVex(G,n);
int j=LocateVex(G,m);
p=new ArcNode;
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
cout<<n<<"->"<<m<<endl;
}
}
void printALGraph(ALGraph G)
{
ArcNode *p;
for(i=0;i<G.vexnum;i++)
{
cout<<G.vertices[i].data<<"->";
p=G.vertices[i].firstarc;
while(p)
{
cout<<p->adjvex<<"->";
p=p->nextarc;
}
cout<<"^"<<endl;
}
}
void BFS_AL(ALGraph G,char v)//从顶点v出发广度优先遍历
{
int queue[MVNum];//队列
int l=0,r=0;//队头,队尾
int s=LocateVex(G,v);
queue[r++]=s;
cout<<G.vertices[s].data;
visited[s]=true;
ArcNode *p;
while(l!=r)
{
p=G.vertices[queue[l++]].firstarc;
while(p)
{
int pos=p->adjvex;
if(!visited[pos])
{
cout<<G.vertices[pos].data;
visited[pos]=true;
queue[r++]=pos;
}
p=p->nextarc;
}
}
cout<<endl;
}
void calculateDN(ALGraph G)//计算有向图每个顶点的出度和入度
{
for(i=0;i<G.vexnum;i++)
{
cout<<G.vertices[i].data<<"的出度为:";
int sum=0;
ArcNode *p=G.vertices[i].firstarc;
while(p)
{
p=p->nextarc;
sum=sum+1;
}
cout<<sum<<"的入度为:";
sum=0;
for(j=0;j<G.vexnum;j++){
p=G.vertices[j].firstarc;
while(p)
{
if(p->adjvex==i)sum=sum+1;
p=p->nextarc;
}
}
cout<<sum<<endl;
}
}
void calculateUDN(ALGraph G)//计算无向图每个顶点的度
{
for(i=0;i<G.vexnum;i++)
{
cout<<G.vertices[i].data<<"的度为:";
int sum=0;
ArcNode *p=G.vertices[i].firstarc;
while(p)
{
p=p->nextarc;
sum=sum+1;
}
cout<<sum<<endl;
}
}
void AL()//建立一个验证操作实现的函数进行测试
{
ALGraph G;
int chose;
while(1){
cout<<"请输入数字 选择是创建 1无向图还是 2有向图"<<endl;
cin>>chose;
if(chose==1)
{
createUDG(G);
break;
}
else if(chose==2)
{
createDG(G);
break;
}
}
printALGraph(G);
BFS_AL(G,G.vertices[0].data);
if(chose==1)
{
calculateUDN(G);
}
else if(chose==2)
{
calculateDN(G);
}
}
void main()
{
int choose;
cout<<"20-8软工2-9-115"<<endl;
while(1){
cout<<"请选择使用 1邻接矩阵 还是 2邻接表"<<endl;
cin>>choose;
if(choose==1){AM();break;}
else if(choose==2){
AL();
break;}
}
}