关于图的基本知识及复习

由于前面的时候就学过图了,但是现在大多都忘了,所以此篇主要于复习

一、图的储存方式

用二维数组存图(邻接矩阵)

其实用二维数组存图是一般常见的手法,但是其时间复杂度就很高,是 n^2,下面就是用二维数组实现的dijkstra算法,看图解

 

 用邻接表存图

邻接表一般是用的链表,为什么要用链表,因为它的时间复杂度比二维数组存图用的太少了,在用二维数组时间超限的时候,就可以用邻接表,它的时间复杂度为n+e

 

代码实现

定义邻接矩阵

const int INF = 0x7fffffff;  //最大值
const int MaxVnum = 100; //顶点最大个数
int visist[MaxVnum] = {0};
typedef char VexType;//顶点的数据类型
typedef int EdgeType;//顶点的边权;若不带权值则用0和1表示其连通性
typedef struct {
	VexType Vex[MaxVnum];//顶点信息
	EdgeType Edge[MaxVnum][MaxVnum];//邻接矩阵
	int vexnum, edgenum; //顶点数和边数
} Gragh;

邻接矩阵的遍历

//深搜
void dfs(Gragh G, int v) { //假设已经创建了一个图的邻接矩阵G ,v是开始访问的顶点
	int w;//w是邻接点
	cout << G.Vex[v] << endl;
	for (w = 0; w < G.vexnum; w++) { //遍历所有顶点
		visist[v] = 1; //访问过了标记为真 
		if (G.Edge[v][w] && !visist[w]) dfs(G, w); //邻接且未被访问过,则递归访问其邻接点
	}
}


//广搜
void bfs(Gragh G, int v) {
	int u, w;
	queue<int>Q;
	visist[v] = 1;
	cout << G.Vex[v] << endl;
	Q.push(v);//顶点v入队
	while (Q.empty() == 0) { //如果队列不空
		u = Q.front(); //队列的头元素出列赋给u
		Q.pop();//队列头元素出队
		for (w = 0; w < G.vexnum; w++) {
			if (G.Edge[u][w] && !visist[w]) { //u,w邻接且w未被访问过
				cout << G.Vex[w] << endl;
				visist[w] = 1;
				Q.push(w);//领接点加入队列
			}
		}
	}
} 

测试

int main(){
	Gragh g;
	cout << "请输入此图的顶点数和边数" << endl;
	cin >> g.vexnum >> g.edgenum;
	getchar();
	cout << "请输入此图的顶点" << endl;
	for(int i = 0; i < g.vexnum; i++){
		cin >> g.Vex[i];
	}
	cout << "请输入关于此图的边信息" << endl;
	for(int i = 0; i < g.vexnum; i++){
		for(int j = 0; j < g.vexnum; j++){
			cin >> g.Edge[i][j];
		}
	}
	
//	dfs(g,0);
	 
//	bfs(g,0);
	
	return 0;
}

二、深度优先搜索

总结一句话,一条路走到底

代码模板

int check(所传参数) 
{
    if(....)return 1;  //满足条件就返回1
    else return 0;
}
 
void dfs(int step)
{
    if(....)  //终止条件
    {
    执行操作
    }
    
     遍历每一种情况
     if(check(参数)) //满足条件
     {
        标记点位;
        进行下一步搜索(如dfs(step+1))
        回溯(有需要时进行回溯)
     }
}
    

三、广度优先搜索

总结一句话,我把周围一层一层走完

代码模板 

1 BFS算法:
 2 
 3 通常用队列(先进先出,FIFO)实现
 4 
 5 初始化队列Q;
 6 Q = {起点s};
 7 标记s为已访问;
 8 while(Q非空)
 9 {
10     取Q队首元素u;
11     u出队;
12     if(u==目标状态)
13     {
14         ……
15     }
16     else
17     {
18         所有与u相邻且未被访问的点进入队列;
19         标记u为已访问;
20     }
21 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值