您的位置:首页 > 理论基础 > 数据结构算法

邻接矩阵的广度优先搜索和深度优先搜索

2010-01-06 18:44 471 查看
      这是今天下午,编了半天的程序,就是邻接矩阵的广度优先搜索和深度优先搜索。

      呵呵,现在想想自己这学期基本上就没编过什么像样的算法程序,这次要不是 MY 拖我帮她写一下这个程序题(她们的实验题),我想这学期就真不会动手写这方面的代码了。

      感觉BFS和DFS在数据结构还是非常重要的,特别是当你能真正用一种语言把它们实现的时候,这样对自己的提高会非常有用。

      印象中,一年在温大学《数据结构》的时候,当时水平特别差,很多时候,老师(李**)讲的原理我都懂,但一说到要动手写,那就真的是大眼瞪小眼了,所以更多的时候,只能照着老师的参考代码,一字一字的copy(ps:其实当时那些参考代码也是错误的,郁闷)。不过我还是庆幸自己咬着牙,硬着头皮坚持学了下来。所以我现在碰到别人问我“怎么学好《数据结构》”的时候,我就会以过来人的角度告诉他“坚持自己把代码实现了,即使你是抄别人的,也要照着别人的代码一个字一个字的敲,决不能直接就Ctrl+C  and Ctrl+V”

     学习方法说好了,我具体讲讲邻接矩阵的广搜和深搜吧

   

     在这里,DFS的实现相对而言比较简单,就是一个思想:递归

void dfs(graph *g,int i){
printf("%d点被访问/n",i);//i已经被访问
visited[i] = 1;//标记i边已经被访问
for(int j=0;j<g->vNum;j++){//对与i点与全部节点进行扫描
if(g->e[i][j]!=0&&visited[j]==0){//假如j点与i点相连,并且j点还没有被访问过
dfs(g,j);//递归方法,对j点进行深度优先搜索
}
}
}

void DFS(graph *g){
int i;
//首先把所有点都设置成没有访问过
for(i=0;i<g->vNum;i++){
visited[i] = 0;
}
//深度优先搜索
for(i=0;i<g->vNum;i++){
if(visited[i]==0){//假如i点没有被访问过
dfs(g,i);//对以邻接矩阵表示的图,以序号为i的顶点为出发点进行深度优先搜索
}
}
printf("/n");
}


 

     广搜的实现相对而言比较难,它需要用到数据结构中另一个抽象:队列

void bfs(graph *g,int i){
int j,k;
printf("%d点被访问/n",i);//i已经被访问
visited[i] = 1;//标记i边已经被访问
cirqueue *p = (cirqueue*)malloc(sizeof(cirqueue));//申请一个对队列
p->front = p->rear = p->count = 0;//表示队列为空
//以下三行代码使得i进入队列
p->q[p->rear] = i;
p->rear = (p->rear++)/maxnum;
p->count++;

while(p->count!=0){//假如队列不空
//以下三行代码是去队列元素
j = p->q[p->front];
p->front = (p->rear++)/maxnum;
p->count--;
//寻找序号为i顶点的邻接点,并做如下处理
for(k=0;k<g->vNum;k++){
if(g->e[j][k]!=0&&visited[k]==0){//假如j点与i点相连,并且j点还没有被访问过
printf("%d点被访问/n",k);//i已经被访问
visited[k] = 1;//标记i边已经被访问

//以下三行代码使得k进入队列
p->q[p->rear] = k;
p->rear = (p->rear++)/maxnum;
p->count++;
}
}
}
}

void BFS(graph *g){
int i;
//首先把所有点都设置成没有访问过
for(i=0;i<g->vNum;i++){
visited[i] = 0;
}
//广度优先搜索
for(i=0;i<g->vNum;i++){
if(visited[i]==0){//假如i点没有被访问过
bfs(g,i);//对以邻接矩阵表示的图,以序号为i的顶点为出发点进行广度优先搜索
}
}

}


 

完整的源代码:

//用邻接矩阵表示的图的深度优先搜索和广度优先搜索
//我这个函数是以无向图为基础
//DFS(深度优先搜索),采用的方法是递归
//BFS(广度优先搜索),采用的是队列的方案,本来c++中是有队列queue这个类的,不过考虑到你们应该是c版本的,我简单写了一个循环队列

//2010年1月6日13:34:49
//writed by zjd

#include<stdio.h>
#include<stdlib.h>//头文件包含malloc函数,用来申请内存空间

const int maxnum = 100;//设置邻接矩阵的最大阶数

//图的邻接矩阵表示结构定义
typedef struct{
int v[maxnum];//图的顶点信息
int e[maxnum][maxnum];//图的边信息
int vNum;//顶点个数
int eNum;//边的个数
}graph;

int visited[maxnum];//标记这个顶点是否被访问过,0表示没有,1表示已经被访问过

//循环队列
typedef struct{
int front;//队列头
int rear;//队列尾
int count;//队列技术
int q[maxnum];//数组表示队列
}cirqueue;

void createGraph(graph *g);//建立图g的函数
void dfs(graph *g,int i);//对以邻接矩阵表示的图,以序号为i的顶点为出发点进行深度优先搜索
void DFS(graph *g);//深度优先搜索
void bfs(graph *g,int i);//对以邻接矩阵表示的图,以序号为i的顶点为出发点进行广度优先搜索
void BFS(graph *g);//广度优先搜索

int main(){
//以下两个语句用来建立用邻接矩阵表示的图
graph *g;
g = (graph*)malloc(sizeof(graph));
createGraph(g);//创建图
printf("深度优先搜索的结果:/n");
DFS(g);
printf("广度优先搜索的结果:/n");
BFS(g);

return 0;
}

void createGraph(graph *g){
int i,j,k;
printf("现在正在创建无向图/n");
printf("请输入定点数和边数/n");
scanf("%d%d",&g->vNum,&g->eNum);//输入定点数和变数
printf("请输入%d个顶点:",g->vNum);

//为了防止原先存在g->e[][]中的数据对今后的搜索造成影响,所以对其进行初始化
for(i=0;i<g->vNum;i++){
for(j=0;j<g->vNum;j++){
g->e[i][j] = 0;
}
}
//输入各个边的具体情况
printf("请输入各个边的边尾和边头:/n");
for(k=0;k<g->eNum;k++){
scanf("%d%d",&i,&j);
g->e[i][j] = 1;//表示点i到点j之间有连接
g->e[j][i] = 1;
}
}

void dfs(graph *g,int i){ printf("%d点被访问/n",i);//i已经被访问 visited[i] = 1;//标记i边已经被访问 for(int j=0;j<g->vNum;j++){//对与i点与全部节点进行扫描 if(g->e[i][j]!=0&&visited[j]==0){//假如j点与i点相连,并且j点还没有被访问过 dfs(g,j);//递归方法,对j点进行深度优先搜索 } } } void DFS(graph *g){ int i; //首先把所有点都设置成没有访问过 for(i=0;i<g->vNum;i++){ visited[i] = 0; } //深度优先搜索 for(i=0;i<g->vNum;i++){ if(visited[i]==0){//假如i点没有被访问过 dfs(g,i);//对以邻接矩阵表示的图,以序号为i的顶点为出发点进行深度优先搜索 } } printf("/n"); }
void bfs(graph *g,int i){ int j,k; printf("%d点被访问/n",i);//i已经被访问 visited[i] = 1;//标记i边已经被访问 cirqueue *p = (cirqueue*)malloc(sizeof(cirqueue));//申请一个对队列 p->front = p->rear = p->count = 0;//表示队列为空 //以下三行代码使得i进入队列 p->q[p->rear] = i; p->rear = (p->rear++)/maxnum; p->count++; while(p->count!=0){//假如队列不空 //以下三行代码是去队列元素 j = p->q[p->front]; p->front = (p->rear++)/maxnum; p->count--; //寻找序号为i顶点的邻接点,并做如下处理 for(k=0;k<g->vNum;k++){ if(g->e[j][k]!=0&&visited[k]==0){//假如j点与i点相连,并且j点还没有被访问过 printf("%d点被访问/n",k);//i已经被访问 visited[k] = 1;//标记i边已经被访问 //以下三行代码使得k进入队列 p->q[p->rear] = k; p->rear = (p->rear++)/maxnum; p->count++; } } } } void BFS(graph *g){ int i; //首先把所有点都设置成没有访问过 for(i=0;i<g->vNum;i++){ visited[i] = 0; } //广度优先搜索 for(i=0;i<g->vNum;i++){ if(visited[i]==0){//假如i点没有被访问过 bfs(g,i);//对以邻接矩阵表示的图,以序号为i的顶点为出发点进行广度优先搜索 } } }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息