数据结构快速回顾——图的遍历

图的遍历指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次。图的遍历操作和树的遍历操作功能相似。图的遍历是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础之上。

图的遍历方法目前有深度优先搜索法和广度(宽度)优先搜索法两种算法。

深度优先搜索法DFS

深度优先搜索法的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi访问,再从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则退回到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点w,从w出发按同样的方法向前遍历,直到图中所有顶点都被访问。

广度优先搜索法BFS

图的广度优先搜索是树的按层次遍历的推广,它的基本思想是:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点vi1,vi2,…, vi t,并均标记已访问过,然后再按照vi1,vi2,…, vi t的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。

具体实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stack>
#include <queue>
#define NODE_SIZE 	100

typedef struct __GRAPH{

	int	n;
	int e;
	int matrix[NODE_SIZE][NODE_SIZE];
}Graph;

//使用栈 递归式深度优先遍历
void DFS_0(Graph g, int v0, bool* visit)
{
	int i,j,k;
	visit[v0] = true;
	printf("visit %d\t",v0);

	for(i =0; i <g.n; i++)
	{
		if(g.matrix[v0][i] != 0 && visit[i] == false)
		{
			DFS_0(g,i,visit);
		}
	}	

}

//使用栈 非递归式深度优先遍历
void DFS(Graph g, int v0)
{
	bool *visit = new bool[g.n];
	int i,j,k;
	for( i =0;i < g.n; i++)
	{
		visit[i] = false;
	}

	visit[v0] = true;
	printf("visit %d\t",v0);
	std::stack<int> s;
	s.push(v0);

	while(!s.empty())
	{
		int tmpNode,i;
		tmpNode = s.top();

		for(i =0; i <g.n; i++)
		{
			if(g.matrix[tmpNode][i] != 0 && visit[i] == false)
			{
				printf("visit %d\t",i);
				visit[i] = true;
				s.push(i);
				break;
			}
		}
		if(i == g.n)
			s.pop();
	}
}

//使用栈 非递归式广度优先遍历
void BFS(Graph g, int v0)
{
	bool *visit = new bool[g.n];
	int i,j,k;
	for( i =0;i < g.n; i++)
	{
		visit[i] = false;
	}

	visit[v0] = true;
	printf("visit %d\t",v0);
	std::queue<int> s;
	s.push(v0);

	while(!s.empty())
	{
		int tmpNode,i;
		tmpNode = s.front();
		s.pop();

		for(i =0; i <g.n; i++)
		{
			if(g.matrix[tmpNode][i] != 0 && visit[i] == false)
			{
				printf("visit %d\t",i);
				visit[i] = true;
				s.push(i);
			}
		}

	}
}

int main()
{
	int m, n;

	while(scanf("%d %d",&n,&m)!= EOF)
	{
		Graph g;
		g.n = n;
		g.e= m;

		int *dist = (int*)calloc(n,sizeof(int));
		int *path = (int*)calloc(n,sizeof(int));

		memset(g.matrix,0,sizeof(int)*NODE_SIZE*NODE_SIZE); 

		int s,t;//边的起点和终点
		for(int i =0; i <m; i++)
		{
			scanf("%d %d",&s,&t);
			if(g.matrix[s][t] > 0)
				continue;
			g.matrix[s][t]=i+1;
			g.matrix[t][s]=g.matrix[s][t];
		}

		DFS(g,0);
		printf("\nDFS_0: \n");

		bool *visit = new bool[g.n];
		for( int i =0;i < g.n; i++)
		{
			visit[i] = false;
		}

		DFS_0(g,0,visit);
		printf("\nBFS_0: \n");
		BFS(g,0);
	}

}

测试用例:

5	5
0 	1
0	2
2 	4
4	1
1	3

对应图为:


参考:http://baike.baidu.com/view/8844138.htm

数据结构快速回顾——图的遍历,布布扣,bubuko.com

时间: 2024-09-29 04:51:40

数据结构快速回顾——图的遍历的相关文章

数据结构快速回顾——平衡二叉树 AVL (转)

平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵树,所以它又叫AVL树.平衡二叉树要求对于每一个节点来说,它的左右子树的高度之差不能超过1,如果插入或者删除一个节点使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态.这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(

数据结构快速回顾——二叉树 解幂子集问题

回溯法是设计递归的一种常用方法,它的求解过程实质上就是一个先序遍历一棵"状态树"的过程,只是这棵树不是遍历前预先建立的而是隐含在遍历过程中的. 下面举一个例子:求含n个元素的集的幂集:集合A={ {1,2,3}, {1,2}, {1,3}, {1}, {2,3},{2},{3},{}}; //{}表示空集合从集合A的每一个元素的角度看,它只有两种状态:或者是属于幂集的元素集,或不属于幂集元素集,则求幂集的过程就可以看成是依次对集合A中的元素进行"取","舍

数据结构快速回顾——二叉树

二叉树(Binary Tree)是个有限元素的集合,该集合或者为空.或者由一个称为根(root)的元素及两个不相交的.被分别称为左子树和右子树的二叉树组成.当集合为空时,称该二叉树为空二叉树.在二叉树中,一个元素也称作一个结点. 基本概念: (1)结点的度.结点所拥有的子树的个数称为该结点的度. (2)叶结点.度为0的结点称为叶结点,或者称为终端结点. (3)分枝结点.度不为0的结点称为分支结点,或者称为非终端结点.一棵树的结点除叶结点外,其余的都是分支结点. (4)左孩子.右孩子.双亲.树中一

数据结构快速回顾——二叉查找树

二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 任意节点的左.右子树也分别为二叉查找树. 没有键值相等的节点(no duplicate nodes). 二叉查找树相比于其他数据结构的优势在于查找.插入的时间复

数据结构快速回顾——栈

堆栈,也可直接称栈,是一种特殊的串行形式的数据结构,它的特殊之处在于只能允许在链结串行或阵列的一端进行加入资料和输出资料的运算.另外堆栈也可以用一维阵列或连结串行的形式来完成. 1 #define STACK_INIT_SIZE 100 2 #define STACKINCREMENT 10 3 4 typedef struct 5 { int* top; 6 int* base; 7 int stacksize; 8 }SqStack; 9 10 int InitStack(SqStack &

数据结构与算法-图的遍历

#include<iostream> #include<string> #include<queue> using namespace std; #define ERROR 1 #define MAX_VERTEX_NUM 100 typedef struct ArcNode{ int adjvex; struct ArcNode *nextarc; string info; }ArcNode; typedef struct VNode{ char date; ArcN

数据结构(15):图 深度优先遍历(DFS)

/*-----------------------------------------------*/ /* 邻接矩阵的DFS */ // 基于 数据结构(14) 中的邻接矩阵的结构 #include <iostream> using namespace std; typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; const int INFINITY = 65535; typedef struct {

数据结构快速回顾——开篇

六月到了.开始找工作的节奏,IT方面知识储备严重欠缺,定计划,更新博客,记录自己的准备历程. 1.数据结构 15天 2.常用算法(排序.动态规划.贪心等) 30天 3.数据挖掘算法 15天 4.移动端.web端开发入门 15天 5.操作系统 10天 共计85天,那时将近9月,还能赶上找工作的大潮. 何为数据结构?数据结构用处?一般来说,使用计算机解决一个问题的时候需要经历以下步骤:分析问题.抽象出数学模型.设计解数学模型的算法.写程序.测试.得到最终结果.为了解决非数值型数学模型,需要使用诸如表

42. 蛤蟆的数据结构笔记之四十二图的遍历之广度优先

42. 蛤蟆的数据结构笔记之四十二图的遍历之广度优先 本篇名言:"生活真象这杯浓酒 ,不经三番五次的提炼呵 , 就不会这样一来可口 ! -- 郭小川" 继续看下广度优先的遍历,上篇我们看了深度遍历是每次一个节点的链表是走到底的. 欢迎转载,转载请标明出处:http://write.blog.csdn.net/postedit/47029275 1.  原理 首先,从图的某个顶点v0出发,访问了v0之后,依次访问与v0相邻的未被访问的顶点,然后分别从这些顶点出发,广度优先遍历,直至所有的