BFS广度优先遍历
这一小节先用邻接表的存储结构实现BFS和DFS 看一下王道课给的例子 邻接矩阵就是二维矩阵
typedef struct{
char Ver[MaxVertexnum];
int Edge[MaxVertexnum][MaxVertexnum];
int Vexnum,arcnum;
}MGraph;
该图对应的邻接矩阵为 ·· A BCD E FG H I J K A 0 1 0 0 1 0 0 0 0 0 0 B 1 0 0 0 0 1 0 0 0 0 0 C 0 0 0 1 0 1 1 0 0 0 0 D 0 0 1 0 0 0 1 1 0 0 0 E 1 0 0 0 0 0 0 0 0 0 0 F 0 1 1 0 0 0 1 0 0 0 0 G 0 0 1 1 0 1 0 1 0 0 0 H 0 0 0 1 0 0 1 0 0 0 0 I -0 0 0 0 0 0 0 0 0 1 1 J -0 0 0 0 0 0 0 0 1 0 1 K -0 0 0 0 0 0 0 0 1 1 0 广度优先遍历的思想很简单,类似于树的层序遍历。 使得遍历的层数尽可能的小。 不知道怎么描述。打个比方 如上图 从1开始的BFS序列为 1 2 5 6 3 7 4 8 9 10 11 #间隔的加粗是同一层的 比如,1是一层 2 5 一层········ 从2开始的BFS序列为 2 1 6 5 3 7 4 8 9 10 11
听了王道的课应该容易理解的。 代码 其中用到了队列相比大家都已经很熟悉了。 结点符号我用A B C D E F G H I J K代替了
void BFS(MGraph &G,LinkQueue &Q,int v);
int FirstNeighbor(MGraph &G,int v){
int i=0;
for(i=0;i<G.Vexnum;i++){
if(G.Edge[v][i]==1) return i;
}
return -1;
}
int NextNeighbor(MGraph &G,int v,int w){
int i=w;
for(i=w+1;i<G.Vexnum;i++){
if(G.Edge[v][i]==1) return i;
}
return -1;
}
void BFSTravese(MGraph &G){
for(int i=0;i<G.Vexnum;i++) visited[i]=false;
LinkQueue Q;
InitQueue(Q);
for(int i=0;i<G.Vexnum;i++){
if(!visited[i]) BFS(G,Q,i);
}
}
void BFS(MGraph &G,LinkQueue &Q,int v){
int w=0;
printf("%c ",G.Ver[v]);
visited[v]=true;
EnQueue(Q,v);
while(!isEmptyQueue(Q)){
DeQueue(Q,v);
for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]){
printf("%c ",G.Ver[w]);
visited[w]=true;
EnQueue(Q,w);
}
}
}
}
DFS深度优先遍历
DFS相对BFS比较简单,用递归的思想实现了。 从1开始的DFS序列: 1 2 6 3 4 7 8 5 9 10 11 一条道走到黑 代码 递归调用的过程,不多赘述了。
void DFS(MGraph &G,int v);
void DFSTraverse(MGraph &G){
for(int i=0;i<G.Vexnum;i++) visited[i]=false;
for(int i=0;i<G.Vexnum;i++){
if(!visited[i]) DFS(G,i);
}
}
void DFS(MGraph &G,int v){
printf("%c ",G.Ver[v]);
visited[v]=true;
int w=0;
for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]) DFS(G,w);
}
}
完整的实现代码
#include<stdio.h>
#include<stdlib.h>
#define MaxVertexnum 11
typedef struct Linknode{
int data;
struct Linknode *next;
}Linknode;
typedef struct{
Linknode *front,*rear;
}LinkQueue;
void InitQueue(LinkQueue &Q){
Q.front=(Linknode*)malloc(sizeof(Linknode));
Q.rear=Q.front;
Q.front->next=NULL;
}
void EnQueue(LinkQueue &Q,int p){
Linknode *S=(Linknode*)malloc(sizeof(Linknode));
S->data=p;
S->next=NULL;
Q.rear->next=S;
Q.rear=S;
}
bool DeQueue(LinkQueue &Q,int &p){
if(Q.front==Q.rear) return false;
Linknode *q=Q.front->next;
p=q->data;
Q.front->next=q->next;
if(q==Q.rear){
Q.rear=Q.front;
}
free(q);
return true;
}
bool isEmptyQueue(LinkQueue Q){
if(Q.front==Q.rear) return true;
else return false;
}
bool visited[MaxVertexnum];
typedef struct{
char Ver[MaxVertexnum];
int Edge[MaxVertexnum][MaxVertexnum];
int Vexnum,arcnum;
}MGraph;
void input_MGraph(MGraph &G){
int x=0,y=0;
for(int i=0;i<MaxVertexnum;i++) G.Ver[i]=65+i;
for(int i=0;i<MaxVertexnum;i++) printf("%c ",G.Ver[i]);
for(int i=0;i<MaxVertexnum;i++){
for(int j=0;j<MaxVertexnum;j++)
G.Edge[i][j]=0;
}
printf("\n请输入图的顶点数:");
scanf("%d",&G.Vexnum);
printf("请输入图的边数:");
scanf("%d",&G.arcnum);
getchar();
for(int i=0;i<G.arcnum;i++){
printf("请输入图边的无序对:");
scanf("%d,%d",&x,&y);
G.Edge[x-1][y-1]=G.Edge[y-1][x-1]=1;
}
for(int i=0;i<MaxVertexnum;i++){
for(int j=0;j<MaxVertexnum;j++)
printf("%d ",G.Edge[i][j]);
printf("\n");
}
}
void BFS(MGraph &G,LinkQueue &Q,int v);
int FirstNeighbor(MGraph &G,int v){
int i=0;
for(i=0;i<G.Vexnum;i++){
if(G.Edge[v][i]==1) return i;
}
return -1;
}
int NextNeighbor(MGraph &G,int v,int w){
int i=w;
for(i=w+1;i<G.Vexnum;i++){
if(G.Edge[v][i]==1) return i;
}
return -1;
}
void BFSTravese(MGraph &G){
for(int i=0;i<G.Vexnum;i++) visited[i]=false;
LinkQueue Q;
InitQueue(Q);
for(int i=0;i<G.Vexnum;i++){
if(!visited[i]) BFS(G,Q,i);
}
}
void BFS(MGraph &G,LinkQueue &Q,int v){
int w=0;
printf("%c ",G.Ver[v]);
visited[v]=true;
EnQueue(Q,v);
while(!isEmptyQueue(Q)){
DeQueue(Q,v);
for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]){
printf("%c ",G.Ver[w]);
visited[w]=true;
EnQueue(Q,w);
}
}
}
}
void DFS(MGraph &G,int v);
void DFSTraverse(MGraph &G){
for(int i=0;i<G.Vexnum;i++) visited[i]=false;
for(int i=0;i<G.Vexnum;i++){
if(!visited[i]) DFS(G,i);
}
}
void DFS(MGraph &G,int v){
printf("%c ",G.Ver[v]);
visited[v]=true;
int w=0;
for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]) DFS(G,w);
}
}
int main(){
MGraph G;
input_MGraph(G);
LinkQueue Q;
InitQueue(Q);
printf("\n广度优先遍历序列:");
BFSTravese(G);
printf("\n深度优先遍历序列:");
DFSTraverse(G);
return 0;
}
结果展示 给的都是从节点1开始遍历的,如果想从其他地方开始,直接先调用BFS,DFS一次在执行DFSTraverse或者BFSTravese。
|