webdancer's Blog
图的搜索
最近学习图论,课程片中理论。但是,觉得还是实现一下好。就根据书上的写了图的BFS和DFS搜索算法。
1.图的实现,邻接链表。
#include<stdlib.h>
typedef struct {int u;int v;} edge;
struct node{int v;struct node * next;};
struct graph{int nv;int ne;struct node ** adj;};
typedef struct graph * Graph;
Graph init(int n){
Graph g=malloc(sizeof *g);// sizeof graph
g->nv=n;
g->ne=0;
g->adj=malloc((sizeof *(g->adj))*n);
int i;
for(i=0;i<g->nv;i++)
g->adj[i]=NULL;
return g;
}
void insert(Graph g,edge e){
int u,v;
u=e.u;
v=e.v;
struct node* unode=malloc(sizeof *unode);
unode->v=v;
unode->next=g->adj[u];
g->adj[u]=unode;
struct node* vnode=malloc(sizeof *vnode);
vnode->v=u;
vnode->next=g->adj[v];
g->adj[v]=vnode;
g->ne++;
}
2.队列实现。
#include<stdlib.h>
static int maxsize=0;
static int front=0;
static int rear=0;
int * queue;
int * initq(int max){
maxsize=max+1;
queue=malloc(sizeof(int)*maxsize);
front=rear=0;
return queue;
}
int add(int * q,int v){
if((rear+1)%maxsize==front)
return -1;
rear=(rear+1)%maxsize;
q[rear]=v;
return v;
}
int delete(int *q){
if(front==rear)
return -1;
front=(front+1)%maxsize;
return q[front];
}
int isempty(){
return (front==rear)?1:0;
}
3.搜索算法。
#include<stdlib.h>
#include<stdio.h>
#include"graph.c"
#include"queue.c"
/*bfs,dfs algos. from "introduction to algos".
*/
#define MAXV 1000
#define BIG (MAXV+1)
#define NUM 100
int color[MAXV];
int d[MAXV];
int p[MAXV];
int f[MAXV];
enum cl {WHITE,GRAY,BLACK};
int * q;
int time;
void bfs(Graph g,int s){
int i;
for(i=0;i<g->ne;i++){
color[i]=WHITE;
d[i]=-1;
p[i]=-1;
}
color[s]=GRAY;
d[s]=0;
p[s]=-1;
q=initq(NUM);
add(q,s);
while(!isempty()){
int u;
u=delete(q);
printf("%d u \n",u);
struct node * vnode=g->adj[u];
while(vnode){
int v;
v=vnode->v;
if(color[v]==WHITE){
color[v]=GRAY;
d[v]=d[u]+1;
p[v]=u;
add(q,v);
}
vnode=vnode->next;
}
color[u]=BLACK;
}
}
void dfsv(Graph g,int u){
color[u]=GRAY;
time++;
d[u]=time;
struct node * vnode;
vnode=g->adj[u];
while(vnode){
int vv;
vv=vnode->v;
if(color[vv]==WHITE){
p[vv]=u;
dfsv(g,vv);
}
vnode=vnode->next;
}
color[u]=BLACK;
time++;
f[u]=time;
}
void dfs(Graph g){
int i,v;
v=g->nv;
for(i=0;i<v;i++){
color[i]=WHITE;
p[i]=-1;
}
time=0;
for(i=0;i<v;i++){
if(color[i]==WHITE)
dfsv(g,i);
}
}
void printpath(Graph g,int s,int v){
if(v==s)
printf("%d ",s);
else if(p[v]==-1)
printf("no path from s to v\n");
else
{
printpath(g,s,p[v]);
printf("%d ",v);
}
}
int main(){
Graph g;
int n=5;
g=init(n);
edge e[7];
e[0].u=0;e[0].v=1;
e[1].u=0;e[1].v=3;
e[2].u=1;e[2].v=2;
e[3].u=1;e[3].v=3;
e[4].u=1;e[4].v=4;
e[5].u=2;e[5].v=4;
e[6].u=3;e[6].v=4;
int i;
for(i=0;i<7;i++)
insert(g,e[i]);
bfs(g,0);
printpath(g,0,4);
printf("\n");
dfs(g);
printpath(g,0,4);
printf("\n");
return 0;
}
CODE过程中,指针的出错还是有,一定要注意动态分配内存的问题,在这个地方很容易出错。还有就是指向指针的指针问题。对于C来说,指针部分得多练多想呀!不知道,谁有好的理解。