数据结构作业——图的存储及遍历(邻接矩阵、邻接表+DFS递归、非递归+BFS)


邻接矩阵存图

/*
* @Author: WZY
* @School: HPU
* @Date:   2018-11-02 18:35:27
* @Last Modified by:   WZY
* @Last Modified time: 2018-11-02 19:48:06
*/
#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define ms(a,b) memset(a,b,sizeof(a))
const int maxn=1e3+10;
using namespace std;
int edge[maxn][maxn];
int vis[maxn];
int DFS[maxn];
int n,m;
inline void add(int x,int y) 
{
	edge[x][y]=1;
}
// 递归DFS
void dfs1(int v,int flag)
{
	if(v>n)
		return ;
	if(flag)
		cout<<"->";
	cout<<v;
	vis[v]=1;	
	flag++;
	for(int i=1;i<=n;i++)
		if((!vis[i])&&edge[v][i])
			dfs1(i,flag);
}
// 非递归DFS
void dfs2(int v,int flag)
{
	ms(vis,0);
	ms(DFS,0);
	int top=1;
	DFS[top]=v;
	while(top)
	{
		int res=DFS[top];
		if(!vis[res])
		{
			vis[res]=1;
			if(flag)
				cout<<"->";
			flag++;
			cout<<res;
			for(int i=n;i>=1;i--)
				if((!vis[i])&&edge[res][i])
					DFS[++top]=i;
		}
		else
			top--;
	}
	cout<<endl;
}
// 查找v的第一个邻接点
int Find_first(int v)
{
	for(int i=1;i<=n;i++)
		if(edge[v][i])
			return i;
	return 0;
}
// 查找v的相对于u的下一个邻接点
int Fint_next(int v,int u)
{
	int i;
	int _=0;
	for(i=1;i<=n;i++)
	{
		if(edge[v][i]&&i==u)
			_=1;
		else if(_==1&&edge[v][i])
			break;
	}
	if(i>n)
		return 0;
	return i;
}
// 非递归
void bfs(int v)
{
	queue<int>q;
	cout<<v;
	vis[v]=1;
	q.push(v);
	while(!q.empty())
	{
		int res=q.front();
		q.pop();
		int u=Find_first(res);
		while(u)
		{
			if(!vis[u])
			{
				cout<<"->"<<u;
				vis[u]=1;
				q.push(u);
			}
			u=Fint_next(res,u);
		}
	}
	cout<<endl;
}
inline void print()
{
	cout<<"建图完成,请输入遍历开始的起点:";
	int v;
	cin>>v;
	cout<<"请选择需要的遍历方式(输入0停止):"<<endl;
	cout<<"1.DFS递归遍历\n2.DFS非递归遍历\n3.BFS非递归遍历"<<endl;
	int __;
	while(cin>>__&&__)
	{
		ms(vis,0);
		if(__==1)
		{
			dfs1(v,0);
			cout<<endl;
		}
		if(__==2)
			dfs2(v,0);
		if(__==3)
			bfs(v);	
	}
}
int main(int argc, char const *argv[])
{
	cout<<"请选择:\n1.有向图\n2.无向图"<<endl;
	int _;
	cin>>_;
	if(_==1)
	{
		cout<<"请输入点的个数及边的个数(用空格隔开):";
		cin>>n>>m;
		int x,y;//两条边+权值
		// 有向图
		for(int i=0;i<m;i++)
		{
			cin>>x>>y;
			add(x,y);
		}
		print();	
	}
	else
	{
		cout<<"请输入点的个数及边的个数(用空格隔开):";
		cin>>n>>m;
		int x,y;//两条边+权值
		// 无向图
		for(int i=0;i<m;i++)
		{
			cin>>x>>y;
			add(x,y);
			add(y,x);
		}
		print();	
	}
	return 0;
}

邻接表存图

/*
* @Author: WZY
* @School: HPU
* @Date:   2018-11-02 18:22:38
* @Last Modified by:   WZY
* @Last Modified time: 2018-11-02 19:35:07
*/
#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define ms(a,b) memset(a,b,sizeof(a))
const int maxn=1e3+10;
using namespace std;
int n,m;
int DFS[maxn];
typedef struct Node
{
	int data;
	Node* Next;
}Edge;
Edge* Node[maxn];
Edge *s;
int vis[maxn];
// 递归
// 查找v的第一个邻接点
int Find_first(int v)
{
	if(Node[v]!=NULL)
		return Node[v]->data;
	return 0;
} 
// 查找v的相对于u的下一个邻接点
int Find_next(int v,int u)
{
	Edge *p=Node[v]; 
	while(p!=NULL)
	{
		if(p->data==u)
			break;
		p=p->Next;
	}
	if(p==NULL)
		return 0;
	p=p->Next;
	if(p!=NULL)
		return p->data;
	return 0;
}
void dfs1(int v,int flag)
{
	if(v>n)
		return ;
	if(flag)
		cout<<"->";
	cout<<v;
	vis[v]=1;	
	flag++;
	int res=Find_first(v);
	while(res)
	{
		if(!vis[res])
			dfs1(res,flag);
		res=Find_next(v,res);
	}
}
// 非递归
void dfs2(int v,int flag)
{
	int temp,w;
	stack<int>s;
	cout<<v;
	vis[v]=1;
	vis[0]=1;
	s.push(v);
	while(!s.empty())
	{
		temp=s.top();  
		w=Find_first(temp);  
		if(!vis[w])
		{
			cout<<"->"<<w;  
			vis[w]=1;
			s.push(w);
		} 
		else
		{       
			w=Find_next(temp,w);  
			while(w)
			{
				if(!vis[w])
				{
					cout<<"->"<<w;
					vis[w]=1;
					s.push(w);
					break;
				} 
				else
					w=Find_next(temp,w);
			}
			if(w==0)  
				s.pop();			
		}	 	
	}
	cout<<endl;
}
void bfs(int v)
{
	queue<int>q;
	vis[v]=1;
	cout<<v;
	q.push(v);
	while(!q.empty())
	{
		int res=q.front();
		q.pop();
		int u=Find_first(res);
		while(u)
		{
			if(!vis[u])
			{
				cout<<"->"<<u;
				vis[u]=1;
				q.push(u);
			}
			u=Find_next(res,u);
		}
	}
	cout<<endl;
}
inline void print()
{
	cout<<"建图完成,请输入遍历开始的起点:";
	int v;
	cin>>v;
	cout<<"请选择需要的遍历方式(输入0停止):"<<endl;
	cout<<"1.DFS递归遍历\n2.DFS非递归遍历\n3.BFS非递归遍历"<<endl;
	int __;
	while(cin>>__&&__)
	{
		ms(vis,0);
		if(__==1)
		{
			dfs1(v,0);
			cout<<endl;
		}
		if(__==2)
			dfs2(v,0);
		if(__==3)
			bfs(v);	
	}
}
inline void add(int x,int y)
{
	s=(Edge*)malloc(sizeof(Edge));
	s->data=y;
	s->Next=Node[x];
	Node[x]=s;
}
inline void init()
{
	for(int i=1;i<maxn;i++)
		Node[i]=NULL;
}
int main(int argc, char const *argv[])
{
	init();
	cout<<"请选择:\n1.有向图\n2.无向图"<<endl;
	int _;
	cin>>_;
	if(_==1)
	{
		cout<<"请输入点的个数及边的个数(用空格隔开):";
		cin>>n>>m;
		int x,y;//两条边+权值
		// 有向图
		for(int i=0;i<m;i++)
		{
			cin>>x>>y;
			add(x,y);
		}
		print();	
	}
	else
	{
		cout<<"请输入点的个数及边的个数(用空格隔开):";
		cin>>n>>m;
		int x,y;//两条边+权值
		// 无向图
		for(int i=0;i<m;i++)
		{
			cin>>x>>y;
			add(x,y);
			add(y,x);
		}
		print();	
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值