图——图的遍历

 深度优先搜索算法(DFS)

例子:

Tr maxu 迷宫探索算法

核心思路:

往前,每到一个十字路口(每个节点因为有多个邻接点就是一个十字路口)就标记这个节点,然后去访问其中的第一个邻接点,不断访问,直到访问到已经到过过的十字路口(即已经标记的节点)就回溯,直到有第二个选择的十字路口(即这个节点还有没被访问过的邻接点)。

以此类推,递归访问所有没被标记的点

一个记录是否去过,一个记录从哪来的

代码实现

void DFS(Graph* G, int k, int* _visit, char** ret)
{
	if (_visit[k] == 0)
	{
		**ret = G->vertexs[k].val;
		(*ret)++;//*ret=*ret + 1改变了指针值,可能导致修改字符串字面量或者已经分配的内存区域之外的位置。
		_visit[k] = 1;
		ENode* p ;//【原代码】= (ENode*)malloc(sizeof(ENode))。内存泄漏,创建了一个新节点,但是没有用
		p = G->vertexs[k].first_edge;
		while (p != NULL)
		{
			DFS(G,p->v_id, _visit, ret);
			p = p->next_edge;
		}
	}
	else
	{
		return;
	}
}

API接口(后面再补吧)

使用API将图像表示和图像处理分离  设计模式   胖子接口

例子

图片上每个像素点看做一个节点,那么通过深度优先搜索可以找到每个与特定像素点颜色相同的色素点,并都将其改变颜色,从而实现PS修图

复杂度:

1.邻接矩阵作为图的存储结构 :O(n^2)

2.邻接表作为图的存储结构:O(n+e)


 

广度优先搜索算法(BFS)

核心思路:

对整个图实现按照离源(第一个访问的点)的距离远近不同分层级逐层访问整个图的所有节点。

代码逻辑:

对于每个节点都优先把他的未访问过的邻接点访问过,并把未访问过的节点放入队列中,只有在这个节点的所有邻接点都访问过后才将该节点从队列中取出,然后依次访问队列中所有节点,直至队列为空。

代码实现:

void BFS(Graph* G, int* _visit, char res[])
{
	//初始化辅助数组(标记是否访问过)
	for (int i = 0; i < MAXVER; i++)
	{
		_visit[i] = 0;
	}

	//构建一个辅助队列
	PQueue a=CreatQueue(MAXVER);
	int count = 0;

	for (int i = 0; i < G->vexnum; i++)//这个循环我本来认为是不必要的,后来发现只有在整个图节点间都是连通时才是不必要的,当存在两个及以上的连通分量时,如果没有这个循环就会遗漏
	{
		if (_visit[i] == 0)
		{
			_visit[i] = 1;
			Insert(a, i);
			while (!Empty(a))
			{
				ENode* p= G->vertexs[a->base[count]].first_edge;//这里刚开始很别扭的点是我想要的是int型的索引,结果队列的数据是char类型,后来意识到两者可以很轻松的转化
				while (p != NULL)
				{
					//将源的邻接点都放入队列中
					if (_visit[p->v_id] == 0)
					{
						Insert(a, p->v_id);
						_visit[p->v_id] = 1;
					}
					p = p->next_edge;
				}
				res[count] = G->vertexs[a->base[count]].val;
				count++;
				char x;
				Delete(a, &x);//这里最开始随便写成了(a,&a),没意识到第二个形参意思是把删除元素的数据放在第二个形参记录下来导致出现问题,所以用别人的函数之前一定要搞清楚它函数的各个参数都是什么意思
			}
		}
	}
	DestroyQueue(a);
}

复杂度:

1.邻接矩阵作为图的存储结构 :O(n^2)

2.邻接表作为图的存储结构:O(n+e)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值