基本图结构和Djiskra最短路径实现

#include 
#include 
#include 

#define MAX_VERTEX_NUM      (100)
#define VERTEX_NAME_SIZE    (20)
#define BIG_NUMBER          (0x9)

typedef unsigned int COST_TYPE;
typedef struct VERTEX
{
    char vertex_name;
    int  vertex_index;
}vertex;

typedef struct EDGE
{
    unsigned int cost;
}edge;

struct graph
{
    vertex  vertex_list[MAX_VERTEX_NUM];
    unsigned int vertex_number;
    edge   edge_matrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
};

typedef struct graph* GRAPH;

int find_vertex(vertex x,GRAPH g)
{
    int pos=-1;
    for(int i=0;ivertex_number;i++)
    {
        if(g->vertex_list[i].vertex_name==x.vertex_name)
        {
            pos=i;
            break;
        }
    }
    return pos;
}

void add_vertex(vertex x,GRAPH g)
{
    if(find_vertex(x,g)==-1)
    {
        g->vertex_list[g->vertex_number]=x;
        g->vertex_number++;
    }

}

void add_edge(vertex x,vertex y,COST_TYPE cost,GRAPH g)
{
    if(find_vertex(x,g)==-1 || find_vertex(y,g)==-1) return;
    g->edge_matrix[x.vertex_index][y.vertex_index].cost=cost;
}

void init_vertex(GRAPH g)
{
    vertex v_a,v_b,v_c,v_d,v_e;

    v_a.vertex_name='a',v_a.vertex_index=0;
    v_b.vertex_name='b',v_b.vertex_index=1;
    v_c.vertex_name='c',v_c.vertex_index=2;
    v_d.vertex_name='d',v_d.vertex_index=3;
    v_e.vertex_name='e',v_e.vertex_index=4;

    add_vertex(v_a,g);
    add_vertex(v_b,g);
    add_vertex(v_c,g);
    add_vertex(v_d,g);
    add_vertex(v_e,g);

    add_edge(v_a,v_b,2,g);
    add_edge(v_a,v_c,2,g);
    add_edge(v_a,v_d,1,g);
    add_edge(v_b,v_c,2,g);
    add_edge(v_b,v_e,1,g);
    add_edge(v_c,v_e,1,g);
    add_edge(v_d,v_e,3,g);


}

void print_graph(GRAPH g)
{
    printf("vertex:\n");
    for(int i=0;ivertex_number;i++)
    {
        printf("%c ",g->vertex_list[i].vertex_name);
    }
    printf("\n");

    printf("edge:\n");
    for(int i=0;ivertex_number;i++)
    {
        for(int j=0;jvertex_number;j++)
        {
            printf("%4d ",g->edge_matrix[i][j].cost);
        }
        printf("\n");
    }
}

GRAPH creat_graph()
{
    GRAPH g=malloc(sizeof(struct graph));
    if(g!=NULL)
    {
        g->vertex_number=0;
        for(int i=0;iedge_matrix[i][j].cost=BIG_NUMBER;
        }
    }
    init_vertex(g);
    return g;
}

void show_path(vertex s,vertex x,GRAPH g,vertex prev[])
{
    if(x.vertex_name==s.vertex_name)
    {
        printf("%c ",s.vertex_name);
        return;
    }
    show_path(s,prev[x.vertex_index],g,prev);
    printf("%c ",x.vertex_name);
}

void djistra(vertex x,GRAPH g)
{
    COST_TYPE* dis=malloc(sizeof(COST_TYPE)*g->vertex_number);
    bool *is_visited=malloc(sizeof(bool)*g->vertex_number);
    vertex *prev=malloc(sizeof(vertex)*g->vertex_number);

    for(int i=0;ivertex_number;i++)
    {
        dis[g->vertex_list[i].vertex_index]=g->edge_matrix[x.vertex_index][g->vertex_list[i].vertex_index].cost;
        is_visited[g->vertex_list[i].vertex_index]=false;
        if(dis[g->vertex_list[i].vertex_index]!=BIG_NUMBER) prev[g->vertex_list[i].vertex_index]=x;
    }

    is_visited[x.vertex_index]=true;

    vertex s_new;
    for(int iter=1;itervertex_number;iter++)
    {
        COST_TYPE min_cost=BIG_NUMBER;
        for(int i=1;ivertex_number;i++)
        {
            if(is_visited[g->vertex_list[i].vertex_index]==false && dis[g->vertex_list[i].vertex_index]<=min_cost)
            {
                min_cost=dis[g->vertex_list[i].vertex_index];
                s_new=g->vertex_list[i];
                //printf("new vertex add :%c\n",s_new.vertex_name);
            }
        }
        is_visited[s_new.vertex_index]=true;
        for(int i=0;ivertex_number;i++)
        {

            if(dis[g->vertex_list[i].vertex_index]>min_cost+g->edge_matrix[s_new.vertex_index][g->vertex_list[i].vertex_index].cost)
            {
                dis[g->vertex_list[i].vertex_index]=min_cost+g->edge_matrix[s_new.vertex_index][g->vertex_list[i].vertex_index].cost;
                prev[g->vertex_list[i].vertex_index]=s_new;
            }
        }

    }

    //display
    for(int i=0;ivertex_number;i++)
    {
        if(g->vertex_list[i].vertex_name!=x.vertex_name)
        {
            printf("Min distance from %c to %c is:%d\n",x.vertex_name,g->vertex_list[i].vertex_name,dis[g->vertex_list[i].vertex_index]);
            show_path(x,g->vertex_list[i],g,prev);
            printf("\n");
        }
    }
    free(dis);
    free(is_visited);
    free(prev);
}

int main()
{
    GRAPH g=creat_graph();
   // print_graph(g);
    vertex x=g->vertex_list[0];
    djistra(x,g);
    free(g);
    return 0;
}

 

你可能感兴趣的:(算法)