在引入图的深度优先搜索之前,为了更加容易理解.先考究一种特殊的图---二叉树的深度优先搜索算法---即二叉树的递归遍历方法.
二叉树的前序遍历算法:
void TreeWalk(node* root) { if(root) { visit(root); TreeWalk(root->left); TreeWalk(root->right); } }
1.如果root不为空,先访问root,
2再递归下降地访问root->left和root->right.
在二叉树中,与root邻接的结点只有left and right.所以,每次只需要递归下降访问这两个节点即可.
对于图来说,可以类比二叉树(特殊情况),总结出一般规律:
1先选定任意一个点vex做为生成树的根结点.访问该根点,
2再递归下降地访问与vex邻接的而且未被访问过的所有结点.
在图中,与vex邻接的结点是不像二叉树一样只有left 和 right,因为是不确定的,因此需要循环地查找判断哪些点邻接并且尚未被访问过.
伪代码:
void DFS(Graph& g,int vex) { Visit vex and Mark vex is visited; for w=FirstAdjacencyVertex to LastAdjacencyVertex(which is not visited before) DFS(g,w) }
//深度优先算法,可以形成一棵树 void DFS(Graph& g,int vex) { cout<<vex<<' '; visited[vex]=true;//is visited int w=FirstAdjVertex(g,vex); while(w>0) { DFS(g,w); w=NextAdjVertex(g,vex,w); } }
//找第一个未被访问过的邻接结点,找不到返回0 int FirstAdjVertex(Graph& g,int vex) { for(int i=1;i<=g.vnum;++i)//从点1开始找与vex邻接的第一个结点 { if(g.edge[vex][i]==1 && !visited[i]) return i; } return 0; } //找下一个未被访问过的邻接结点 int NextAdjVertex(Graph& g,int vex,int w) { for(int i=w;i<=g.vnum;++i)//从w开始,找下一个未被访问过的邻接结点 { if(g.edge[vex][i]==1 && !visited[i])//若i与vex邻接且i未访问过,下一次遍历,就从这个点往下. return i; } return 0;//点都从1开始,返回0则所以点已访问过 }
void DFS_traver(Graph& g) { for(int i=1;i<=g.vnum;++i) { if(!visited[i])//如果i结点未被访问过,形成森林 DFS(g,i); } }
int visited[8]; void BFS(int edge[][8],int vex) { queue<int> q; //visited[vex] = 1; //标记已被访问过 q.push(vex); //初始化队列 while(!q.empty()) { vex=q.front(); q.pop(); //取出队头数据 if(!visited[vex]) { cout<<vex<<' '; visited[vex] = 1; //标记已被访问过 } for ( int j=0; j<8; ++j ) { if(edge[vex][j] == 1 && !visited[j] ) //邻接未被访问过的结点入队 { q.push(j); } } } } void BFS_traver(int g[][8]) { int i; for(i=0;i<8;i++) visited[i]=0; for(i=0;i<8;++i) { if(!visited[i]) { BFS(g,i); //如果i结点未被访问过,形成森林 } } }
原文地址:http://blog.csdn.net/yusiguyuan/article/details/43198979