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来说,指针部分得多练多想呀!不知道,谁有好的理解。




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee