图的基本操作与实现
[问题描述]
自选存储结构,实现对图的操作。
[基本要求]
(1)自选存储结构,输入含n个顶点(用字符表示顶点)和e条边的图G;
(2)求每个顶点的度,输出结果;
(3)指定任意顶点x为初始顶点,对图G作DFS遍历,输出DFS顶点序列(提示:使用一个栈实现DFS);
(4)指定任意顶点x为初始顶点,对图G作BFS遍历,输出BFS顶点序列(提示:使用一个队列实现BFS);
(5)输入顶点x,查找图G:若存在含x的顶点,则删除该结点及与之相关联的边,并作DFS遍历(执行操作3);否则输出信息“无x”;
(6)判断图G是否是连通图,输出信息“YES”/“NO”;
(7)如果选用的存储结构是邻接矩阵,则用邻接矩阵的信息生成图G的邻接表,即复制图G, 然后再执行操作(2);反之亦然。
代码:选邻接矩阵作为存储结构
#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
queue<int>q;
class Graph
{
public:
int n;
char dot[10];
int a[10][10];
int visited[10];
public:
void ini();
void degree(char);
void del(char);
void dfs(char,bool);
void bfs(char);
bool isConnected();
void change();
~ Graph();
};
Graph::~ Graph(){
}
void Graph::ini(){
memset(visited,0,sizeof(visited));
memset(a,0,sizeof(a));
int i, j, m, p, q;
char x,y,z;
cout<<"请输入图中点的个数:"<<endl;
cin>>n;
cout<<"请输入图的点集,以空格分开:"<<endl;
for(j=0;j<n;j++)
cin>>dot[j];
cout<<"请输入图中边的个数:"<<endl;
cin>>m;
cout<<"请输入图的边集:"<<endl;
for(i=0;i<m;i++){
cin>>x>>y;
for(p=0;p<n;p++)
if(x==dot[p])
break;
for(q=0;q<n;q++)
if(y==dot[q])
break;
if(p==n||q==n) cout<<"输入错误!"<<endl;
else a[p][q]=a[q][p]=1;
}
for (i = 0;i < n;i++) {
for (j = 0;j < n;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
void Graph::degree(char c){
int i,j,deg=0;
for(i=0;i<n;i++)
if(dot[i]==c)
break;
for(j=0;j<n;j++)
deg+=a[i][j];
cout<<"定点"<<c<<"的度为:"<<deg<<endl;
}
void Graph::dfs(char c,bool b){//递归实现
if(b)
cout<<c<<" ";
int i,j;
for(i=0;i<n;i++)
if(dot[i]==c)
break;
visited[i]=1;
for(int w=0;w<n;w++)
if((a[i][w]!=0)&&(!visited[w]))
dfs(dot[w],b);
}
void Graph::bfs(char c){//队列实现
cout<<c<<" ";
int i,u;
for(i=0;i<n;i++)
if(dot[i]==c)
break;
visited[i]=1;
q.push(i);
while(!q.empty()){
u=q.front();
q.pop();
for(int w=0;w<n;w++)
if((a[u][w]!=0)&&(!visited[w])){
cout<<dot[w]<<" ";
visited[w]=1;
q.push(w);
}
}
}
void Graph::del(char ch){
int i,j,k;
for(i=0; i<n; i++) ///遍历顶点数组
if(ch==dot[i])
break;
if(i==n){
cout<<"无"<<ch<<endl; //如果循环正常结束则i=g->vexnum,此时说明不存在该顶点
return ;
}
else{
for(j=0; j<n; j++) ///如果存在,则将与顶点相关的边覆盖
for(k=0; k<n; k++){
if(j>=i&&k>=i)
a[j][k]=a[j+1][k+1];
if(j>=i&&k<i)
a[j][k]=a[j+1][k];
if(j<i&&k>=i)
a[j][k]=a[j][k+1];
}
}
for(j=0; j<n; j++) ///覆盖该顶点
if(j>=i)
dot[j]=dot[j+1];
n--;
cout<<"删除该顶点后剩余顶点为:\n";
for(j=0; j<n; j++)
cout<<dot[j]<<" ";
cout<<endl;
cout<<"删除后邻接矩阵为:\n";
for(j=0; j<n; j++)
{
for(k=0; k<n; k++)
cout<<a[j][k]<<" ";
cout<<endl;
}
memset(visited,0,sizeof(visited));
cout<<"从第一个顶点开始的DFS遍历为:";
dfs(dot[0],true);
}
bool Graph::isConnected(){
memset(visited,0,sizeof(visited));
dfs(dot[0],false);
for(int i=0;i<n;i++)
if(visited[i]==0){
return false;
}
return true;
}
void Graph::change(){
for(int i=0;i<n;i++){
memset(visited,0,sizeof(visited));
dfs(dot[i],true);
cout<<endl;
}
}
int main(){
Graph graph;
graph.ini();
for(int i=0;i<graph.n;i++)
graph.degree(graph.dot[i]);
char x;
cout<<"请输入深搜起点: ";
cin>>x;
graph.dfs(x,true);
cout<<endl;
memset(graph.visited,0,sizeof(graph.visited));
cout<<"请输入广搜起点: ";
cin>>x;
graph.bfs(x);
cout<<endl;
cout<<"是否是连通图: ";
if(graph.isConnected())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
cout<<"请输入欲删除的顶点:";
cin>>x;
graph.del(x);
cout<<endl<<"转换成邻接表:"<<endl;;
graph.change();
for(int i=0;i<graph.n;i++)
graph.degree(graph.dot[i]);
return 0;
}