深度搜索:优先深度扫描,如果当前路径走到了死胡同,那么,又依次访问上次访问过的节点的可走路径。就这样如此往复,最终完成图的遍历。
深度搜索类似于树的前序遍历
广度搜索:优先广度扫描,假设你前面现在有N条路可走,AB…N,那么先把AB…N的所有节点访问一遍。每次访问之后都把当前所走路径的下一条路径(若存在)则存入队列,这样,当前路径走完之后,又重复上述步骤,直至遍历完所有节点。
广度搜索类似于树的层次遍历
以下为邻接表的两种遍历方式的实现:
运行如下图:
#include <iostream>
#include <malloc.h>
using namespace std;
#define maxSize 100
/*边结构*/
typedef struct ArcNode{
int adjvex; // 该边中入度节点下标
struct ArcNode *nextarc; //下一条边
int info; //权值
}ArcNode;
/*顶点表结构*/
typedef struct VNode{
char data;//顶点信息
ArcNode *firstNode;//相当于边集合的表头
}VNode;
/* 图 */
typedef struct AGraph{
VNode adjList[maxSize];//邻接表
int n,e;//顶点数和边数
}AGraph;
/* 创建图 */
void createGraph(AGraph &graph);
void dfs(AGraph g,int v);
void bfs(AGraph g,int v);
void clearArray(int *array,int size);
// 辅助数组
static int *visit;
int main(int argc, char** argv) {
AGraph graph;
createGraph(graph);
visit = (int*)malloc(sizeof(int)*graph.n);
clearArray(visit,graph.n);
cout<<"深度遍历:" ;
dfs(graph,0);
clearArray(visit,graph.n);
cout<<endl<<"广度遍历:" ;
bfs(graph,0);
return 0;
}
void createGraph(AGraph &graph){
cout<<"输入节点数以及边数:";
cin>>graph.n>>graph.e;
cout<<"输入顶点信息:";
//初始化节点
for(int i=0; i<graph.n; i++){
cin>>graph.adjList[i].data;
graph.adjList[i].firstNode = NULL;
}
cout<<"输入边信息:";
for(int k=0; k<graph.e; k++){
int i ,j;
cin>>i>>j;
ArcNode *p = new ArcNode;
// 设置边的另一个节点的下标位置
p->adjvex = j;
// 设置为 第 i个节点的边
p->nextarc = graph.adjList[i].firstNode;
// 调整头指针
graph.adjList[i].firstNode = p;
}
}
// 深度优先遍历算法
void dfs(AGraph g,int v){
// 边节点
ArcNode *p;
visit[v] = 1;
// 访问当前节点
cout<<g.adjList[v].data<<" ";
// 指向当前节点的首条边
p = g.adjList[v].firstNode;
while( p != NULL){
// 如果未访问
if( visit[p->adjvex] == 0){
// 优先深度遍历 递归访问当前节点首条边的另一端节点
dfs(g,p->adjvex);
}
// 走投无路的时候,才去访问自己节点的边
p = p->nextarc;
}
}
void bfs(AGraph g,int v){
ArcNode *p;
int que[maxSize];
int real=0,front=0;
visit[v] = 1;
// 访问入口节点
cout<<g.adjList[v].data<<" ";
real = (real+1) % maxSize;
// 入口节点入队
que[real] = v;
while ( front != real ){
// 出队
front = (front +1) % maxSize;
// 访问出队节点的第一条边
p = g.adjList[ que[front] ].firstNode;
// 如果该节点的边未完全访问
while( p != NULL ){
// 如果未访问
if( visit[p->adjvex] == 0 ){
visit[p->adjvex] = 1;
// 输出节点
cout<<g.adjList[p->adjvex].data<<" ";
real = (real+1) % maxSize;
// 入队访问节点
que[real] = p->adjvex;
}
//该节点的下一条边
p = p->nextarc;
}
}
}
void clearArray(int *array,int size){
for(int i = 0;i < size; i++){
array[i] = 0;
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容