| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 601 人关注过本帖
标题:关于最短路径图算法实现的问题
取消只看楼主 加入收藏
moranhgirl
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2013-12-29
结帖率:0
收藏
已结贴  问题点数:20 回复次数:0 
关于最短路径图算法实现的问题
我参考《算法精解》中用单链表实现算法的代码,但在编写 main 函数时,运行出来会遇到图顶点插入出错,第一个顶点插入时会成功,但是第二个顶点之后似乎没有被插入图中,希望大神指教:

这里是 main 函数:

程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "list.h"
#include "set.h"
#include "graph.h"
#include "example.h"
#include "graphalg.h"

#define DBL_MAX 20

int _match(const void *key1, const void *key2)
{
    if(key1 == key2)
        return 0;
    else
        return 1;
}

void _destroy(void *data)
{
    free(data);
}


int main()
{
    example();
    return 0;
}


程序代码:
#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <stdio.h>

int _match(const void *key1, const void *key2);
void _destroy(void *data);
int example();

#endif


程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "list.h"
#include "set.h"
#include "graph.h"
#include "graphalg.h"
#include "example.h"
    
int example()
{
    Graph _graph;
    Graph *graph = &_graph;
    List _list,
         *list = &_list;
    PathVertex pvertex1, pvertex2,
               *pathvertex1 = &pvertex1, *pathvertex2 = &pvertex2;
    int i = 0;
    void *data;
    ListElmt *element;
    char _city[6] = {'a','b','c','d','e','f'},
         (*city)[6] = &_city;

    double A_B = 8,
           A_C = 4,
           B_C = 6,
           B_D = 2,
           C_F = 1,
           C_E = 4,
           F_B = 2,
           F_D = 7,
           F_E = 4;


    int (*match)(const void *key1, const void *key2);
    void (*destroy)(void *data);

    /*Match and destroy function. Use void pointer to realize.*/
    match = &_match;
    destroy = &_destroy;

    graph_init(graph, match, destroy);
    for(i; i < 6; ++i)
    {
        pathvertex1 -> data = &_city[i];
        graph_ins_vertex(graph, (const PathVertex *)pathvertex1;
    }
//        printf("%c\n", *(char *)pathvertex_data(pathvertex1));
//    }
//    for(element = list_head(&graph -> adjlists); element != NULL; element = list_next(element)
//    {
//            data = ((AdjList *)list_data(element)) -> vertex;
//            pathvertex1 = (PathVertex *)data;
//            printf("%c\n", *(char *)(pathvertex_data(pathvertex1)));
//}
//    pathvertex1 -> data = &_city[0];
//    pathvertex2 -> data = &_city[1];
//    graph_ins_edge(graph, (const PathVertex *)pathvertex1, (const PathVertex *)pathvertex2, A_B);


//    pathvertex1 -> data = &_city[0];
//    shortest(graph, pathvertex1, list, match);

    return 0;
}



下面是最短路径完整算法:


程序代码:
/*list.h*/

#ifndef LIST_H
#define LIST_H

#include <stdlib.h>


 
typedef struct ListElmt_
{
    void *data;
    struct ListElmt_ *next;
} ListElmt;


 
typedef struct List_
{
    int size;
    int (*match)(const void *key1, const void *key2);
    void (*destroy)(void *data);
    ListElmt *head;
    ListElmt *tail;
} List;


 
void list_init(List *list, void (*destroy)(void *data));
void list_destroy(List *list);
int list_ins_next(List *list, ListElmt *element, const void *data);
int list_rem_next(List *list, ListElmt *element, void **data);
#define list_size(list) ((list) -> size)

#define list_head(list) ((list) -> head)
#define list_tail(list) ((list) -> tail)
#define list_is_head(list, element) ((element) == (list) -> head ? 1 : 0)
#define list_is_tail(list, element) ((element) -> next == NULL ? 1 : 0)
#define list_data(element) ((element) -> data)
#define list_next(element) ((element) -> next)

#endif


程序代码:
#include"list.h"
#include "graph.h"
#include "graphalg.h"
#include "list.h"
#include "set.h"

/*list_init*/
void list_init(List *list,void (*destroy)(void *data)) {
     
    list -> size = 0;
    list -> destroy = destroy;
    list -> head = NULL;
    list -> tail = NULL;

    return;
}


 
void list_destroy(List *list) {
    void *data;
     
    while (list_size(list) > 0) {
        if (list_rem_next(list, NULL, (void **)&data) == 0 && list -> destroy != NULL) {
             

            list -> destroy(data);
        }
    }

     
    memset(list, 0, sizeof(List));
    return;
}


 
int list_ins_next(List *list, ListElmt *element, const void *data) {
    ListElmt      *new_element;

    if ((new_element = (ListElmt *)malloc(sizeof(ListElmt))) == NULL)
        return -1;

    new_element -> data = (void *)data;
    if(element == NULL) {
               if (list_size(list) == 0)
            list -> tail = new_element;

        new_element -> next = list -> head;
        list -> head = new_element;
    }
    else {

        if (element -> next == NULL)
            list -> tail = new_element;

        new_element -> next = element -> next;
        element -> next = new_element;
    }
     
    list -> size++;

    return 0;
}


 
int list_rem_next(List *list, ListElmt *element, void **data) {
    ListElmt       *old_element;

     
    if (list_size(list) == 0)
        return -1;

     
    if (element == NULL)
    {

         
        *data = list -> head -> data;
        old_element = list -> head;
        list -> head = list -> head -> next;

        if (list_size(list) == 1)
        list -> tail = NULL;
    }

    else
    {
         
        if (element -> next == NULL)
            return -1;
        *data = element -> next -> data;
        old_element = element -> next;
        element -> next = element -> next -> next;

        if (element -> next == NULL)
        list -> tail = element;
    }

     
    free(old_element);

     
    list -> size--;
    return 0;
}


程序代码:
/* set.h */
#ifndef SET_H
#define SET_H

#include <stdlib.h>
#include "list.h"


 

typedef List Set;

  

void set_init(Set *set, int (*match)(const void *key1, const void *key2), void (*destroy)(void *data));

#define set_destroy list_destroy
int set_insert(Set *set, const void *data);
int set_remove(Set *set, void **data);
int set_union(Set *setu, const Set *set1, const Set *set2);
int set_intersection(Set *seti, const Set *set1, const Set *set2);
int set_difference(Set *setd, const Set *set1, const Set *set2);
int set_is_member(const Set *set, const void *data);
int set_is_subset(const Set *set1, const Set *set2);
int set_is_equal(const Set *set1, const Set *set2);
#define set_size(set) ((set) -> size)

#endif


程序代码:
/* set.c */
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "set.h"


 
void set_init(Set *set, int (*match)(const void *key1, const void *key2),
              void (*destroy)(void *data))
{
     
    list_init(set, destroy);
    set -> match = match;

    return;
}


 
int set_insert(Set *set, const void *data)
{
     
    if (set_is_member(set, data))
    return 1;
    
     
    return list_ins_next(set, list_tail(set), data);
}

 
int set_remove(Set *set, void **data)
{
    ListElmt *member, *prev;

     
    prev = NULL;

    for(member = list_head(set); member != NULL; member = list_next(member))
    {
    if(set -> match(*data, list_data(member)))
        break;
    prev = member;
    }


    if (member == NULL)
        return -1;
    

    return list_rem_next(set, prev, data);
}


 
int set_union(Set *setu, const Set *set1, const Set *set2)
{
    ListElmt *member;
    void     *data;


    set_init(setu, set1 -> match, NULL);

    for (member = list_head(set1); member != NULL; member = list_next(member))
    {
    data = list_data(member);
    if(list_ins_next(setu, list_tail(setu), data) != 0)
    {
        set_destroy(setu);
        return -1;
    }
    }

     
    for (member = list_head(set2); member != NULL; member = list_next(member))
    {
    if(set_is_member(set1, list_data(member)))
    {
        continue;
    }
    else
    {
        data = list_data(member);
        if(list_ins_next(setu, list_tail(setu), data) != 0)
        {
            set_destroy(setu);
            return -1;
        }
    }
    }
    return 0;
}


 
int set_intersection(Set *seti, const Set *set1, const Set *set2)
{
    ListElmt *member;
    void *data;


    set_init(seti, set1 -> match, NULL);


 
    for (member = list_head(set1); member != NULL; member = list_next(member))
    {
    if(set_is_member(set2, list_data(member)))
    {
        data = list_data(member);
        if(list_ins_next(seti, list_tail(seti), data) != 0)
        {
            set_destroy(seti);
            return -1;
        }
    }
    }
    return 0;
}


 
int set_difference(Set *setd, const Set *set1, const Set *set2)
{
    ListElmt *member;
    void     *data;


 
    set_init(setd, set1 -> match, NULL);


 
    for(member = list_head(set1); member != NULL; member = list_next(member))
    {
    if (!set_is_member(set2, list_data(member)))
    {
        data = list_data(member);

        if(list_ins_next(setd, list_tail(setd), data) != 0)
        {
            set_destroy(setd);
            return -1;
        }
    }
    }
    return 0;
}


 
int set_is_member(const Set *set, const void *data)
{
    ListElmt *member;


 
    for(member = list_head(set); member != NULL; member = list_next(member))
    {
    if(set->match(data,list_data(member)))
        return 1;
    }
    return 0;
}
    

 
int set_is_subset(const Set *set1, const Set *set2)
{
    ListElmt *member;


 
    if(set_size(set1) > set_size(set2))
        return 0;


 
    for(member = list_head(set1); member != NULL; member = list_next(member))
    {
    if (!set_is_member(set2,list_data(member)))
        return 0;
    }
    return 1;
}


 
int set_is_equal(const Set *set1, const Set *set2)
{

 
    if(set_size(set1) != set_size(set2))
    return 0;


 
    return set_is_subset(set1, set2);
}



程序代码:
/* graph.h */
#ifndef GRAPH_H
#define GRAPH_H
#include <stdlib.h>
#include "list.h"
#include "set.h"

 
typedef struct AdjList_
{
    void *vertex;
    Set adjacent;
}AdjList;

 
typedef struct Graph_
{
    int vcount;
    int ecount;
    int (*match)(const void *key1, const void *key2);
    void (*destroy)(void *data);
    List adjlists;
}Graph;

 
typedef enum VertexColor_{white, black}VertexColor;

 
void graph_init(Graph *graph, int (*match)(const void *key1, const void *key2),void (*destroy)(void *data));
void graph_destroy(Graph *graph);
int graph_ins_vertex(Graph *graph, const void *data);
int graph_ins_edge(Graph *graph, const void *data1, const void *data2, double data3);
int graph_rem_vertex(Graph *graph, void **data);
int graph_rem_edge(Graph *graph, void *data1, void **data2);
int graph_adjlist(const Graph *graph, const void *data, AdjList **adjlist);
int graph_is_adjacent(const Graph *graph, const void *data1, const void *data2);
#define graph_adjlists(graph) ((graph) -> adjlists)
#define graph_vcount(graph) ((graph) -> vcount)
#define graph_ecount(graph) ((graph) -> ecount)
#endif


程序代码:
#include <stdlib.h>
#include <string.h>

#include "graph.h"
#include "graphalg.h"
#include "list.h"
#include "set.h"

//graph_init
void graph_init(Graph *graph, int (*match)(const void *key1, const void *key2), void(*destroy)(void *data))
{
    graph -> vcount = 0;
    graph -> ecount = 0;
    graph -> match = match;
    graph -> destroy = destroy;

    list_init(&graph -> adjlists, NULL);

    return;
}

void graph_destroy(Graph *graph)
{
    AdjList *adjlist;

    while(list_size(&graph -> adjlists) > 0)
    {
        if(list_rem_next(&graph -> adjlists, NULL, (void **)&adjlist) == 0)
        {
            set_destroy(&adjlist -> adjacent);
            if(graph -> destroy != NULL)
                graph -> destroy(adjlist -> vertex);
                free(adjlist);
        }
    }
    list_destroy(&graph -> adjlists);

 
    memset(graph, 0, sizeof(Graph));
    return;
}

 
int graph_ins_vertex(Graph *graph, const void *data)
{
    ListElmt *element;
    AdjList *adjlist;
    int retval;

    for(element = list_head(&graph -> adjlists); element != NULL; element = list_next(element))
    {
        if(graph -> match(data, ((AdjList *)list_data(element)) -> vertex))
            return 1;
    }

    if((adjlist = (AdjList *)malloc(sizeof(AdjList))) == NULL)
        return -1;


      adjlist -> vertex = (void *)data;
      set_init(&adjlist -> adjacent, graph -> match, NULL);
      if((retval = list_ins_next(&graph -> adjlists, list_tail(&graph -> adjlists), adjlist)) != 0) 
      {
       return retval;
      }
    graph -> vcount++;
    return 0;
}

 
int graph_ins_edge(Graph *graph, const void *data1, const void *data2, double data3)
{
    ListElmt *element;
    int retval;

    for(element = list_head(&graph -> adjlists); element != NULL; element = list_next(element))
    {
        
    if(graph -> match(data2, ((AdjList *)list_data(element)) -> vertex))
    {
                data = ((AdjList *)list_data(element)) -> vertex;
                pathvertex = (PathVertex *)data;
                pathvertex -> weight = data3;
                break;
        }
    }
    if(element == NULL)
    return -1;

    for(element = list_head(&graph -> adjlists); element != NULL; element = list_next(element))
    {
    if(graph -> match(data1, ((AdjList*)list_data(element)) -> vertex))
        break;
    }
    if(element == NULL)
        return -1;
     
    if((retval = set_insert(&((AdjList *)list_data(element)) -> adjacent, data2)) != 0)
    {
    return retval;
    }
     

    graph -> ecount++;
    return 0;
}

 
int graph_rem_vertex(Graph *graph, void **data)
{
  ListElmt *element, *temp, *prev;
  AdjList  *adjlist;
  int found;
   
  prev = NULL;
  found = 0;
  
  for(element = list_head(&graph -> adjlists); element != NULL; element = list_next(element))
  {
     if(set_is_member(&((AdjList *)list_data(element)) -> adjacent, *data))
        return -1;
      
    if(graph -> match(*data, ((AdjList *)list_data(element)) -> vertex))
    {
    temp = element;
    found = 1;
    }
   
     
   if(!found)
     prev = element;
  }
    
   if(!found)
      return -1;
    
   if(set_size(&((AdjList *)list_data(temp)) -> adjacent) > 0)
     return -1;
    
   if(list_rem_next(&graph -> adjlists, prev,(void **)&adjlist) != 0)
      return -1;
     
   *data = adjlist -> vertex;
   free(adjlist);
    
   graph -> vcount--;
   return  0;
}
   
int graph_rem_edge(Graph *graph, void *data1, void **data2)
{
   ListElmt  *element;
      
   for(element = list_head(&graph -> adjlists); element != NULL; element = list_next(element))
   {
       if(graph -> match(data1, ((AdjList *)list_data(element)) -> vertex))
          break;
   }
   if(element == NULL)
      return -1;
   
   if(set_remove(&((AdjList *)list_data(element)) -> adjacent, data2) != 0)
       return -1;
   
   graph -> ecount--;
   return 0;
}
  
int graph_adjlist(const Graph *graph, const void *data, AdjList **adjlist)
{
   ListElmt  *element, *prev;
    
   prev = NULL;
   for(element = list_head(&graph -> adjlists); element != NULL; element = list_next(element))
   {
       if(graph -> match(data, ((AdjList *)list_data(element)) -> vertex))
           break;
       prev = element;
   }
   
   if(prev == NULL)
      return -1;
   
   *adjlist = list_data(element);
   return 0;
}
   
int graph_is_adjacent(const Graph  *graph, const void *data1, const void *data2)
{
  ListElmt  *element,*prev;
    
  prev = NULL;
  for(element = list_head(&graph -> adjlists); element != NULL; element=list_next(element))
  {
      if(graph -> match(data1, ((AdjList *)list_data(element)) -> vertex))
         break;
      prev = element;
  }
    
  if(prev == NULL)
     return 0;
   
  return set_is_member(&((AdjList *)list_data(element)) -> adjacent, data2);
}       
    


程序代码:
/*graphalg.h*/
#ifndef GRAPHALG_H
#define GRAPHALG_H

#include <stdio.h>

#include "graph.h"
#include "list.h"

/*Define a structure for vertices in shortest-path problems.*/
typedef struct PathVertex_
{
    void *data;
    double weight;

    VertexColor color;
    double  d;

    struct PathVertex_ *parent;
}PathVertex;



/*Public Interface*/
int shortest(Graph *graph, PathVertex *start, List *paths , int (*match)(const void *key1, const void *key2));
#define pathvertex_data(element) ((element) -> data)

#endif


程序代码:
#include <float.h>
#include <stdio.h>
#include <stdlib.h>

#include "graph.h"
#include "graphalg.h"
#include "list.h"
#include "set.h"

/*relax*/
static void relax(PathVertex *u, PathVertex *v, double weight)
{
    /*relax an edge between two vertices u and v.*/
    if (v -> d > u -> d + weight)
    {
        v -> d = u -> d + weight;
        printf("%lf\n", v -> d);
        v -> parent = u;
    }
    return;
}

/*shortest*/
int shortest(Graph *graph, PathVertex *start, List *paths, int (*match)(const void *key1, const void *key2))
{
    AdjList *adjlist;
    PathVertex *pth_vertex,
               *adj_vertex,
               *pathvertex;
    ListElmt *element,
             *member;
    double minimum;
    int found,
        i;
    FILE *fp;
    void *data;


    /*initialize all of the vertices in the graph.*/
    found = 0;

    for(element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element))
    {
        pth_vertex = ((AdjList *)list_data(element)) -> vertex;
        if (match(pth_vertex, start))
        {
            /*initialize the start vertex.*/
            pth_vertex -> color = white;
            pth_vertex -> d = 0;
            pth_vertex -> parent = NULL;
            found = 1;
        }
        else
        {
            /* initialize vertices other than the start vertex.*/
            pth_vertex -> color = white;
            pth_vertex -> d = DBL_MAX;
            pth_vertex -> parent = NULL;
        }
    }

    /* return if the start vertex was not found.*/
    if(!found)
        return -1;

    /*use Dijkstra's algorithm to compute shortest paths from the start vertex.*/
    i = 0;

    while (i < graph_vcount(graph))
    {
        /*Select the white vertex with the smallest shortest-path estimate.*/
        minimum = DBL_MAX;

        for(element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element))
        {
            pth_vertex = ((AdjList *)list_data(element)) -> vertex;

            if(pth_vertex -> color == white && pth_vertex -> d < minimum)
            {
                minimum = pth_vertex -> d;
                adjlist = list_data(element);
            }
        }

        /*color the selected vertex black.*/
        ((PathVertex *)adjlist -> vertex) -> color = black;

        /*traverse each vertex adjacent to the selected vertex.*/
        for(member = list_head(&adjlist -> adjacent); member != NULL; member = list_next(member))
        {
            adj_vertex = list_data(member);

            /*find the adjacent vertex in the list of adjacency-list structures.*/
            for (element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element))
            {
                pth_vertex = ((AdjList *)list_data(element)) -> vertex;

                if(match(pth_vertex, adj_vertex))
                {
                    /*relax the adjacent vertex in the list of adjacency-list structures.*/
                    relax(adjlist -> vertex, pth_vertex, adj_vertex -> weight);
                }
            }
        }

        /*prepare to select the next vertex.*/
        ++i;
    }

//    fp = fopen("example_map", "a+");
//    fprintf(fp, "起始城市 到达城市 最短距离\n");
//    fclose(fp);

    /* load the vertices with their path information into a list.*/
    list_init(paths, NULL);

    for(element = list_head(&graph_adjlists(graph)); element != NULL; element = list_next(element))
    {
        /*load each black vertex from the list of adjacency-list structures.*/
        pth_vertex = ((AdjList *)list_data(element)) -> vertex;

        if(pth_vertex -> color == black)
        {
            if(list_ins_next(paths, list_tail(paths), pth_vertex) != 0)
            {
                list_destroy(paths);
                return -1;
            }
//            else
//            {
//            pathvertex = (PathVertex *)pth_vertex;
//            printf("%c\n", *(char *)(pathvertex_data(pathvertex)));
//            fp = fopen("example_map", "a+");
//            fprintf(fp, "%c         %c         %lf\n", *(char )pathvertex_data(start), *(char)pathvertex_data(pathvertex), pth_vertex -> d);
//            fclose(fp);
//            }
        }

    }
    return 0;
    
    
}
搜索更多相关主题的帖子: color 
2013-12-29 15:19
快速回复:关于最短路径图算法实现的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.038058 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved