#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;
}