关于图的搜索有两种:广度优先(bfs)深度优先 (dfs)。
以下图为例:

深度优先的基本思想简单说就是搜到底,重新搜。从v0为起点进行搜索,如果被访问过,则做一个标记,直到与v0想连通的点都被访问一遍,如果这时,仍然有点没被访问,可以从中选一个顶点,进行再一次的搜索,重复上述过程,所以深度优先的过程也是递归的过程。
深度优先访问的结果是:
0->1->3->7->4->2->5->6
广度优先的基本思想是,从顶点v0出发,访问与v0相邻的点,访问结束后,再从这些点出发,继续访问,直到访问结束为止。标记被访问过的点同深搜一下,不过,广度优先一般需要用到队列。
上图广度优先的结果:0->1->2->3->4->5->6->7
对于深度优先与广度优先的应用,在吴军的《数学之美》一书中有过介绍。
关于搜索代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#define maxn 100
using namespace std;
typedef struct
{
int edges[maxn][maxn]; //邻接矩阵
int n; //顶点数
int e; //边数
}MGraph;
bool vis[maxn]; //标记顶点是否被访问过
void createGraph(MGraph &G) //用引用做参数
{
int i,j;
int s,t; //存储顶点的编号
int v; //存储边的权值
for(i=0;i<G.n;i++) //初始化
{
for(j=0;j<G.n;j++)
{
G.edges[i][j] = 0;
}
vis[i] = false;
}
for(i = 0;i<G.e;i++) //对邻接矩阵的边赋值
{
scanf("%d%d%d",&s,&t,&v); //输入边顶点的编号以及权值
G.edges[s][t] = v;
}
}
void dfs(MGraph G,int v)
{
int i;
printf("%d ",v); //访问结点v
vis[v] = true;
for(int i = 0;i<G.n;i++) //访问与v相邻且未被访问过的结点
{
if(G.edges[v][i]!=0&&vis[i]==false)
{
dfs(G,i);
}
}
}
void dfs1(MGraph G,int v) //非递归实现(用到了栈,其实在递归的实现过程,仍是用到了栈,所以。。。)
{
stack<int> s;
printf("%d",v); //访问初始的结点
vis[v]=true;
s.push(v); //入栈
while(!s.empty())
{
int i,j;
i=s.top(); //取栈顶顶点
for(j=0;j<G.n;j++) //访问与顶点i相邻的顶点
{
if(G.edges[i][j]!=0&&vis[j]==false)
{
printf("%d ",j); //访问
vis[j]=true;
s.push(j); //访问完后入栈
break; //找到一个相邻未访问的顶点,访问之后跳出循环
}
}
if(j==G.n) //如果与i相邻的顶点都被访问过,则将顶点i出栈
s.pop();
}
}
void bfs(MGraph G,int v)
{
queue<int> Q;
printf("%d",v);
vis[v] = true;
Q.push(v);
while(!Q.empty())
{
int i,j;
i = Q.front(); //取队首顶点
Q.pop();
for(j=0;j<G.n;j++) //广度遍历
{
if(G.edges[i][j]!=0&&vis[j]==false)
{
printf("%d",j);
vis[j]=true;
Q.push(j);
}
}
}
}
int main()
{
int n,e; //建图的顶点数和边数
while(scanf("%d%d",&n,&e)==2&&n>0)
{
MGraph G;
G.n = n;
G.e = e;
createGraph(G);
dfs(G,0);
printf("\n");
// dfs1(G,0);
// printf("\n");
// bfs(G,0);
// printf("\n");
}
return 0;
}
/*测试数据:
8 9
0 1 1
1 3 1
1 4 1
3 7 1
4 7 1
0 2 1
2 5 1
5 6 1
2 6 1
*/