数据结构 - 图的创建与遍历

文章目录

要求

分别基于邻接矩阵和邻接表存储结构实现图的基本运算,要求:
⑴ 能根据输入的顶点、边/弧的信息建立图;
⑵实现图中顶点、边/弧的插入、删除;
⑶实现对该图的深度优先遍历;
⑷实现对该图的广度优先遍历。

代码


/*

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛阳八中我最棒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值