要求
分别基于邻接矩阵和邻接表存储结构实现图的基本运算,要求:
⑴ 能根据输入的顶点、边/弧的信息建立图;
⑵实现图中顶点、边/弧的插入、删除;
⑶实现对该图的深度优先遍历;
⑷实现对该图的广度优先遍历。
代码
/*
7
0 3 3 2 1
111 3 1 2 3
222 3 1 2 3
333 3 1 2 3
444 1 6
555 0
666 0
3
777 2 9 8
888 1 9
999 1 7
2
0 5 1
3 6 1
3
0 5
3 6
4 6
3
0
1
4
*/
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#define Maxv 66
//vertex顶点 arc 弧 Adjacency list邻接表
typedef int ElemType;
int visit[Maxv]; //节点是否访问过
using namespace std;
int visitcnt=0;
typedef struct nodea{
int adj;
int weight; //权重,这个好像可以不做
struct nodea *next;
}ANode,*ANodep; //弧
typedef struct{
ElemType data;
ANode *firstarc;
}VNode; //顶点
typedef struct nodev{
VNode vexs[Maxv];
int vexnum;
int arcnum;
}ALGraph;
void CreateGraph(ALGraph &graph){
graph.vexnum=0;
graph.arcnum=0;
cout<<"创建图模块"<<endl;
cout<<"请输入图的结点个数n,再输入n行数据(数据 出度 位置)"<<endl;
int t;
cin>>t;//结点个数
graph.vexnum=t;
for(int i=0;i<t;i++){
int d,n;
cin>>d>>n;
graph.arcnum+=n;
graph.vexs[i].data=d;
ANodep newarc,head,lastp;
head=(ANodep)malloc(sizeof(ANode));
head->next=NULL;
if(!head) exit (-1);
graph.vexs[i].firstarc=head;
lastp=head;
while(n--){
int out;
cin>>out;
ANodep newarc=(ANodep)malloc(sizeof(ANode));
if(!newarc) exit(-1);
lastp->next=newarc;
newarc->next=NULL;
newarc->adj=out;
newarc->weight=1; //默认权重都是1
lastp=lastp->next;
}
}
graph.arcnum/=2;
}
void BFS(ALGraph graph,int ii){
// cout<<"BFS"<<ii<<endl;
queue<int> q;
q.push(ii);
while( !q.empty()){
int tem=q.front();
q.pop();
if(!visit[tem]){
visit[tem]=1;
cout<<graph.vexs[tem].data<<' ';
visitcnt++;
ANodep nowp=graph.vexs[tem].firstarc->next;
while(nowp!=NULL){
// cout<<nowp->adj<<endl;
q.push(nowp->adj);
nowp=nowp->next;
}
}
}
}
void DFS(ALGraph graph,int ii){
// cout<<"DFS"<<ii<<endl;
if(visit[ii]==0){
cout<<graph.vexs[ii].data<<' ';
visitcnt++;
visit[ii]=1;
ANodep nownode=graph.vexs[ii].firstarc->next;
while(nownode){
DFS(graph,nownode->adj);
nownode=nownode->next;
}
}
return ;
}
void DeleteArc(ALGraph &graph){
cout<<"删除弧模块"<<endl;
cout<<"请输入您要删除的弧的个数"<<endl;
int arcnum1;
cin>>arcnum1;
while(arcnum1--){
cout<<"请输入您要删除的弧的弧尾和弧头"<<endl;
int t,h;
cin>>t>>h;
graph.arcnum--;
ANodep lastp=graph.vexs[t].firstarc;
ANodep nowp;
while(lastp->next->adj!=h && lastp->next!=NULL)
lastp=lastp->next;
lastp->next=lastp->next->next;
}
}
void DeleteVex(ALGraph &graph){
cout<<"顶点删除模块"<<endl;
cout<<"请输入要删除的顶点下标" <<endl;
int vexid;
cin>>vexid;
for(int i=vexid;i<graph.vexnum-1;i++){
graph.vexs[i].data=graph.vexs[i+1].data;
graph.vexs[i].firstarc=graph.vexs[i+1].firstarc;
}
for(int i=0;i<graph.vexnum-1;i++){
ANodep nowp=graph.vexs[i].firstarc;
while(nowp->next!=NULL){
if(nowp->next->adj>vexid)
nowp->next->adj--;
else if(nowp->next->adj==vexid)
nowp->next=nowp->next->next;
nowp=nowp->next;
}
}
graph.vexnum--;
}
void InsertVex(ALGraph &graph){
cout<<"插入顶点模块"<<endl;
int num=graph.vexnum;
cout<<"请输入要插入的顶点个数n,再输入n行数据(数据 出度 位置)" <<endl;
int t;
cin>>t;
graph.vexnum+=t;
if(t+num>Maxv){
cout<<"太多存不下了"<<endl;
return ;
}
for(int i=0;i<t;i++){
int d,n;
cin>>d>>n;
graph.arcnum+=n;
graph.vexs[i+num].data=d;
ANodep newarc,head,lastp;
head=(ANodep)malloc(sizeof(ANode));
head->next=NULL;
if(!head) exit (-1);
graph.vexs[i+num].firstarc=head;
lastp=head;
while(n--){
int out;
cin>>out;
ANodep newarc=(ANodep)malloc(sizeof(ANode));
if(!newarc) exit(-1);
lastp->next=newarc;
newarc->next=NULL;
newarc->adj=out;
newarc->weight=1; //默认权重都是1
lastp=lastp->next;
}
}
}
void InsertArc(ALGraph &graph){
cout<<"插入弧模块"<<endl;
cout<<"请输入要插入弧的个数"<<endl;
int num;
cin>>num;
while(num--){
cout<<"请依次输入弧尾和弧头的下标,弧的权重"<<endl;
int t,h,w;
cin>>t>>h>>w;
graph.arcnum++;
ANodep lastp=graph.vexs[t].firstarc->next;
ANodep nowp;
while(lastp->next!=NULL)
lastp=lastp->next;
nowp=(ANodep)malloc(sizeof(ANode));
if(!nowp) exit (-1);
nowp->weight=w;
nowp->adj=h;
lastp->next=nowp;
}
}
void output(ALGraph graph){
cout<<"\n输出邻接表"<<endl;
for(int i=0;i<graph.vexnum;i++)
{
cout<<graph.vexs[i].data<<' ';
ANodep nowp=graph.vexs[i].firstarc->next;
while(nowp!=NULL){
cout<<' '<<nowp->adj;
nowp=nowp->next;
}
cout<<endl;
}
cout<<endl;
}
int main()
{
ALGraph graph;
graph.arcnum=0;
graph.vexnum=0;
CreateGraph(graph);
output(graph);
int i=0;
memset(visit,0,sizeof(visit));
cout<<"深搜"<<endl;
while(visitcnt<graph.vexnum){
while(visit[i]) i++;
DFS(graph,i);
}
cout<<endl;
memset(visit,0,sizeof(visit));
visitcnt=0;
i=0;
cout<<"广搜"<<endl;
while(visitcnt<graph.vexnum){
while(visit[i]) i++;
BFS(graph,i);
}
cout<<endl;
//插入顶点
InsertVex(graph);
memset(visit,0,sizeof(visit));
visitcnt=0;
i=0;
cout<<"广搜输出"<<endl;
while(visitcnt<graph.vexnum){
while(visit[i]) i++;
BFS(graph,i);
}
cout<<endl;
output(graph);
//插入弧
InsertArc(graph);
memset(visit,0,sizeof(visit));
visitcnt=0;
i=0;
cout<<"广搜输出"<<endl;
while(visitcnt<graph.vexnum){
while(visit[i]) i++;
BFS(graph,i);
}
cout<<endl;
output(graph);
//删除弧
DeleteArc(graph);
memset(visit,0,sizeof(visit));
visitcnt=0;
i=0;
cout<<"广搜输出"<<endl;
while(visitcnt<graph.vexnum){
while(visit[i]) i++;
BFS(graph,i);
}
cout<<endl;
output(graph);
//删除顶点
cout<<"请输入要删除顶点个数"<<endl;
int nn;
cin>>nn;
while(nn--)
DeleteVex(graph);
memset(visit,0,sizeof(visit));
visitcnt=0;
i=0;
cout<<"广搜输出"<<endl;
while(visitcnt<graph.vexnum){
while(visit[i]) i++;
BFS(graph,i);
}
output(graph);
return 0;
}