图论Graph Theory(1):图的表示法及遍历

一、图的表示法

1.邻接表

1.1采用STL中vector存图
vector<int>G[N];
G[v].push_back(u);//v点与u点联通
1
5
6
9
7
2
3
8
4

例如:

连接的点
G[1]5 6
G[2]7
G[3]8
G[4]
G[5]9
G[6]5 9
G[7]1
G[8]4
G[9]1
1.2采用链表的连接方式存图

2.邻接矩阵

2.1采用二维数组存取邻接矩阵

m a p [ i ] [ j ] = { t r u e 若存在边edge(i,j) f a l s e 其他情况 map[i][j]= \begin{cases} true& \text{若存在边edge(i,j)}\\ false& \text{其他情况} \end{cases} map[i][j]={truefalse若存在边edge(i,j)其他情况

bool map[N][N];
map[i][j]=true;//i,j存在边

二、图的遍历

2.1深度优先搜索(DepthFirestSearch)

时间复杂度:显然邻接表为O(|V|+|E|),邻接矩阵为O(|V|^2)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
const int N = 100005;

struct E{
	int u,v;
	//E(int a,int b){u=a,v=b;}
};

vector<int>G[N];
vector<E>edge;
bool vis[N];

void dfs(int num){
	vis[num]=true;
	for(int i=0;i<G[num].size();i++){
		if(!vis[G[num][i]]){
			struct E temp;
			temp.u=num;
			temp.v=G[num][i];
			edge.push_back(temp);
			dfs(G[num][i]);
		}
	}
}
void depthFirstSearch(const int n){
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			dfs(i);
		}
	}
	for(int i=0;i<edge.size();i++){//输出边集
		cout<<edge[i].u<<" "<<edge[i].v<<endl;
	}
}
int main(){

	int n=0,m=0;	\\n个顶点,m条边
	int u=0,v=0;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
	}

	depthFirstSearch(n);

	return 0;
}

样例输入

9 9
1 5
1 6
1 7
2 7
3 8
4 8
5 6
5 9
6 9

样例输出

1 5
5 6
6 9
1 7
7 2
3 8
8 4

2.2广度优先搜索(BreadFirestSearch)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
using namespace std;
const int N = 100005;

struct E{
	int u,v;
	//E(int a,int b){u=a,v=b;}
};
vector<int>G[N];
vector<E>edge;
bool vis[N];
queue<int>enqueue;

void breadFirstSearch(const int n){
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			enqueue.push(i);
			vis[i]=true;
			while(!enqueue.empty()){
				int num=enqueue.front();
				enqueue.pop();
				for(int j=0;j<G[num].size();j++){
					if(!vis[G[num][j]]){
						vis[G[num][j]]=true;
						struct E temp;
						enqueue.push(G[num][j]);
						temp.u=num;
						temp.v=G[num][j];
						edge.push_back(temp);
					}
				}
			}
		}
	}
	//输出查找边集
	for(int i=0;i<edge.size();i++){
		cout<<edge[i].u<<" "<<edge[i].v<<endl;
	}
	return;
}
int main(){

	int n=0,m=0;
	int u=0,v=0;
	
	cin>>n>>m;

	for(int i=1;i<=m;i++){
		cin>>u>>v;
		G[u].push_back(v);	//无向图
		G[v].push_back(u);
	}

	breadFirstSearch(n);

	return 0;
}

样例输入

9 10
1 5
1 6
1 7
1 9
2 7
3 8
4 8
5 6
5 9
6 9

样例输出

1 5
1 6
1 7
1 9
7 2
3 8
8 4
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
第1章 绪论 1.1 简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。 解:数据是对客观事物的符号表示。在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。 数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。 数据对象是性质相同的数据元素的集合,是数据的一个子集。 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。 存储结构是数据结构在计算机中的表示。 数据类型是一个值的集合和定义在这个值集上的一组操作的总称。 抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。是对一般数据类型的扩展。 1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。 解:抽象数据类型包含一般数据类型的概念,但含义比一般数据类型更广、更抽象。一般数据类型由具体语言系统内部定义,直接提供给编程者定义用户数据,因此称它们为预定义数据类型。抽象数据类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所进行的操作。在定义抽象数据类型中的数据部分和操作部分时,要求只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接口。 1.3 设有数据结构(D,R),其中 , , 试按图论的画法惯例画出其逻辑结构。 解:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值