C语言实现图的广度优先搜索遍历算法

Python014

C语言实现图的广度优先搜索遍历算法,第1张

先写个大题思路,楼主先自己想想,想不出来的话,2天后给代码。

queue<node>q

q.push(start)

bool canVisit[][]

node cur

while(!q.empty()){

cur = q.top()

q.pop()

foreach(node is connected by cur){

if(canVisit[node.x][node.y])

{

printf("访问结点(%d,%d)",node.x,node.y)

canVisit[node.x][node.y]=false

q.push(node)

}

}

}

它没有固定的写法, 但是大框都差不多, 一定要使用队列, 因为队列的存在可以维护程序按照广度优先的方式进行搜索。即层次遍历

可以给你一份我作过的一个题的代码,大体上就是这个样子

/****************************************************\

*

* Title : Rescue

* From : HDU 1242

* AC Time : 2012.01.12

* Type : 广度优先搜索求最短步数

* Method :从目标结点向回搜索,初始结点有多个

*

\****************************************************/

#include <stdio.h>

#include <string.h>

#define DATASIZE 201

#define QUEUESIZE 65536

typedef struct

{

int x,y

}CPOINT

int bfs(char map[][DATASIZE], int n, int m, CPOINT cpa)

int direction[][2] = {{1,0},{-1,0},{0,1},{0,-1}}

int main(void)

{

int m,n,i,j,res

CPOINT cpa

char map[DATASIZE][DATASIZE]

freopen("c:\\in.data","r",stdin)

while(scanf("%d%d%*c",&n,&m) != EOF) {

for(i = 0 i <n i++) {

gets(map[i])

for(j = 0 j <m j++) {

if(map[i][j] == 'a') {

cpa.x = i

cpa.y = j

}

}

}

res = bfs(map, n, m, cpa)

if(res) {

printf("%d\n",res)

} else {

printf("Poor ANGEL has to stay in the prison all his life.\n")

}

}

return 0

}

int bfs(char map[][DATASIZE], int n, int m, CPOINT cpa)

{

CPOINT q[QUEUESIZE],u,np

int vis[DATASIZE][DATASIZE],step[DATASIZE][DATASIZE],i,front,rear,res

memset(q, 0, sizeof(q))

memset(vis, 0, sizeof(vis))

memset(step, 0, sizeof(step))

front = rear = res = 0

q[rear++] = cpa

vis[cpa.x][cpa.y] = 1

step[cpa.x][cpa.y] = 0

while(front <= rear) {

u = q[front++]

if(map[u.x][u.y] == 'r') {

res = step[u.x][u.y]

break

}

for(i = 0 i <4i++) {

np.x = u.x + direction[i][0]

np.y = u.y + direction[i][1]

if(np.x >= 0 &&np.x <n &&np.y >= 0 &&np.y <m &&!vis[np.x][np.y] &&map[np.x][np.y] != '#' ) {

vis[np.x][np.y] = 1

q[rear++] = np

step[np.x][np.y] = step[u.x][u.y] + 1

if(map[np.x][np.y] == 'x') {

++step[np.x][np.y]

}

}

}

}

return res

}

/*深度优先*/

#include<stdio.h>

#include<stdlib.h>

struct node/*图的顶点结构*/

{

int vertex

int flag

struct node *nextnode

}

typedef struct node *graph

struct node vertex_node[10]

void creat_graph(int *node,int n)

{

graph newnode,p/*定义一个新结点及指针*/

int start,end,i

for(i=0i<ni++)

{

start=node[i*2]/*边的起点*/

end=node[i*2+1]/*边的终点*/

newnode=(graph)malloc(sizeof(struct node))

newnode->vertex=end/*新结点的内容为边终点处顶点的内容*/

newnode->nextnode=NULL

p=&(vertex_node[start])/*设置指针位置*/

while(p->nextnode!=NULL)

p=p->nextnode/*寻找链尾*/

p->nextnode=newnode/*在链尾处插入新结点*/

}

}

void dfs(int k)

{

graph p

vertex_node[k].flag=1/*将标志位置1,证明该结点已访问过*/

printf("vertex[%d]",k)

p=vertex_node[k].nextnode/*指针指向下个结点*/

while(p!=NULL)

{

if(vertex_node[p->vertex].flag==0)/*判断该结点的标志位是否为0*/

dfs(p->vertex)/*继续遍历下个结点*/

p=p->nextnode/*若已遍历过p指向下一个结点*/

}

}

main()

{

graph p

int node[100],i,sn,vn

printf("please input the number of sides:\n")

scanf("%d",&sn)/*输入无向图的边数*/

printf("please input the number of vertexes\n")

scanf("%d",&vn)

printf("please input the vertexes which connected by the sides:\n")

for(i=0i<4*sni++)

scanf("%d",&node[i])/*输入每个边所连接的两个顶点,起始及结束位置不同,每边输两次*/

for(i=1i<=vni++)

{

vertex_node[i].vertex=i/*将每个顶点的信息存入数组中*/

vertex_node[i].nextnode=NULL

}

creat_graph(node,2*sn)/*调用函数创建邻接表*/

printf("the result is:\n")

for(i=1i<=vni++)/*将邻接表内容输出*/

{

printf("vertex%d:",vertex_node[i].vertex)/*输出顶点内容*/

p=vertex_node[i].nextnode

while(p!=NULL)

{

printf("->%3d",p->vertex)/*输出邻接顶点的内容*/

p=p->nextnode/*指针指向下个邻接顶点*/

}

printf("\n")

}

printf("the result of depth-first search is:\n")

dfs(1)/*调用函数进行深度优先遍历*/

printf("\n")

}

/***************************广度优先*******************************/

#include <stdio.h>

#include <stdlib.h>

struct node

{

int vertex

struct node *nextnode

}

typedef struct node *graph

struct node vertex_node[10]

#define MAXQUEUE 100

int queue[MAXQUEUE]

int front = - 1

int rear = - 1

int visited[10]

void creat_graph(int *node, int n)

{

graph newnode, p/*定义一个新结点及指针*/

int start, end, i

for (i = 0i <ni++)

{

start = node[i *2]/*边的起点*/

end = node[i *2+1]/*边的终点*/

newnode = (graph)malloc(sizeof(struct node))

newnode->vertex = end/*新结点的内容为边终点处顶点的内容*/

newnode->nextnode = NULL

p = &(vertex_node[start])/*设置指针位置*/

while (p->nextnode != NULL)

p = p->nextnode

/*寻找链尾*/

p->nextnode = newnode/*在链尾处插入新结点*/

}

}

int enqueue(int value) /*元素入队列*/

{

if (rear >= MAXQUEUE)

return - 1

rear++/*移动队尾指针*/

queue[rear] = value

}

int dequeue() /*元素出队列*/

{

if (front == rear)

return - 1

front++/*移动队头指针*/

return queue[front]

}

void bfs(int k) /*广度优先搜索*/

{

graph p

enqueue(k)/*元素入队*/

visited[k] = 1

printf("vertex[%d]", k)

while (front != rear)

/*判断是否对空*/

{

k = dequeue()/*元素出队*/

p = vertex_node[k].nextnode

while (p != NULL)

{

if (visited[p->vertex] == 0)

/*判断其是否被访问过*/

{

enqueue(p->vertex)

visited[p->vertex] = 1/*访问过的元素置1*/

printf("vertex[%d]", p->vertex)

}

p = p->nextnode/*访问下一个元素*/

}

}

}

main()

{

graph p

int node[100], i, sn, vn

printf("please input the number of sides:\n")

scanf("%d", &sn)/*输入无向图的边数*/

printf("please input the number of vertexes\n")

scanf("%d", &vn)

printf("please input the vertexes which connected by the sides:\n")

for (i = 0i <4 *sni++)

scanf("%d", &node[i])

/*输入每个边所连接的两个顶点,起始及结束位置不同,每边输两次*/

for (i = 1i <= vni++)

{

vertex_node[i].vertex = i/*将每个顶点的信息存入数组中*/

vertex_node[i].nextnode = NULL

}

creat_graph(node, 2 *sn)/*调用函数创建邻接表*/

printf("the result is:\n")

for (i = 1i <= vni++)

/*将邻接表内容输出*/

{

printf("vertex%d:", vertex_node[i].vertex)/*输出顶点内容*/

p = vertex_node[i].nextnode

while (p != NULL)

{

printf("->%3d", p->vertex)/*输出邻接顶点的内容*/

p = p->nextnode/*指针指向下个邻接顶点*/

}

printf("\n")

}

printf("the result of breadth-first search is:\n")

bfs(1)/*调用函数进行深度优先遍历*/

printf("\n")

}