昨天让这两个搜索算法搞的萎靡不振的,今天重新来过。其实昨天理解不好的原因还是对图的存储结构部了解,上两篇文章用到的其实图的邻接矩阵存储的。存储图一个数组是不够的需要两个数组才可以,一个是存储节点的vex数组,用来控制每个节点都被访问到。第二个就是一个边关系的二维数组。具体的结构是这样的
节点数组int vex[]
1 2 3 4 5
vex[0] = v1;vex[0] = v2;vex[0] = v3;vex[0] = v4;vex[0] = v5;
边关系数组也就是我们一直说的邻接矩阵,只不过是一个二维数组int arc[][],行和列都是代表了节点数组中的节点,因此其最大值也就是vex.length。,arc[i][j]表示的是arc[i]和arc[j]之间的有无边,若有则等于1,否则为0.理解了这个再去了解DFS和BFS就很轻松了,从DFS开始。
DFS的算法理解思路:
这样再来分析算法就比较好理解了:
bool visited[max]//访问控制数组 vex[];//顶点元素数组 arc[][];//边关系矩阵 void DFSTraverse(Grap G){ for(v=0;v<G.vex.length;++v){ visited[v] = false; }//初始化标记数组 for(v=0;v<vex.lengthlv++){ if(!visited[v]){ DFS(G,v); } }/遍历每个节点,确保每个节点都被访问到 } void DFS(Graph G,int v){ int j; visit(v); visited[v] = true; for(j=0;j<G.vex.length;j++){//遍历arc数组的第i行 if(G.arc[i][j] == 1 && !visited[j]){ DFS(G,j); }//若vex[j]和vex[i]之间有边关系,且没被访问过,则对vex[j]递归调用DFS }//for }BFS广度优先搜索:
和DFS不同广度优先搜索类似于层次遍历,直观的表达就是DFS倾向于找到一个节点就去和这节点有关系(即有边关系的)的节点,然后再去找和这个新节点有边关系的节点,因此才得名深度优先搜索。广度优先搜索就是倾向于找到和一点节点有变关系的所有的节点,然后再去找另一个节点有边关系的所有节点,因此得名广度优先搜索。从BFS算法的思路上可以看出,我们要保证先被访问的节点优先,因此选择辅助队列。
具体的算法思路如下:
bollean visited[max];//访问标记数组 Queue Q;//用到的复制队列 vex[];//顶点数组 arc[][];//边数组 void BFSTraverse(Graph G){ for(i=0;i<G.vex.length;i++){ visisted[i] = false; }//初始化标记数组 for(i=0;i<G.vex.legth;i++){ if(!visisted[i]){ BFS(G,i); } }//遍历节点数组确保每个节点都访问 }//BFSTraverse void BFS(Graph G,int v){ visit(v); visited[v] = true; Q.add(v); while(!Q.empty()){ v = Q.poll(); for(j=0;j<G.vex.length;j++){ if(G.arc[i][j]==1 && !visited[j]){ visited[j] = true; visit(G.vex[j]); Q.add(j); } } }//while }//BFS