【问题标题】:Graph implementation, functions and parameters. What makes more sense?图形实现、函数和参数。什么更有意义?
【发布时间】:2009-09-09 04:31:28
【问题描述】:

只是为了“有趣”,我正在开发 C 语言算法简介 (Cormen) 一书中显示的几乎所有算法(如果可能)。我已经阅读了图表章节,但我不确定如何设计我的函数,但首先看看我的数据结构(希望这能澄清我的问题)。

typedef struct s_multi_matrix
    {
        int                 width;
        int                 height;
        int                 depth;
        multi_matrix_type   type;   // stores either MMTYPE_INT or MMTYPE_RECORD enums to know where to read values (ivals or rvals)
        int *               ivals;
        DT_record *         rvals;
    } DT_multi_matrix;

typedef struct s_double_linked_list
    {
        DT_record   *   sentinel;
    } DT_double_linked_list;

typedef struct s_record // multi purpose structure
    {
        int key;
        enum e_record_type  type; // stores either TYPE_INT, TYPE_SZ, TYPE_FLOAT, TYPE_VOID to know how to use the data union
        union
        {
            int     ival;
            char *  sval;
            float   fval;
            void *  vval;
        } data;
        struct s_record * left, // for trees, disjoint sets and linked lists
                        * right,
                        * parent;
    } DT_record;


typedef struct s_graph  // this is the structure I'm focusing on right now
    {
        graph_type              type;       // GRAPH_DIRECTED or GRAPH_UNDIRECTED
        graph_adj_type          adj_type;   // ADJ_LIST or ADJ_MATRIX
        edge_type           etype;  // WEIGHTED or NOT_WEIGHTED
        union
        {
            DT_double_linked_list *     list;
            DT_multi_matrix *           matrix;
        } adjacency;
    } DT_graph;

所以,我正在考虑几个函数来操作 DT_graph 类型:

// takes a pointer to a pointer to a graph, allocates memory and sets properties
void build_graph(DT_graph ** graph_ptr, graph_type gtype, graph_adj_type atype);
// prints the graph in file (using graphviz)
void print_graph(DT_graph * graph, char * graph_name);

这是棘手的部分,因为我的图形类型有几种不同的类型组合(无向和加权边、有向和加权边、无向和非加权边、有向和非加权边……)我想知道哪个是函数的最佳方法:

void dgraph_add_wedge(DT_graph * graph, DT_record * u, DT_record * v, int weight);
void ugraph_add_wedge(DT_graph * graph, DT_record * u, DT_record * v, int weight);
void dgraph_add_nwedge(DT_graph * graph, DT_record * u, DT_record * v);
void ugraph_add_nwedge(DT_graph * graph, DT_record * u, DT_record * v);

前两个将加权顶点添加到有向/无向图中,后两个将做同样的事情,但没有任何与边相关的权重。 我想到的另一种方法是这样的:

void graph_add_edge(DT_graph * graph, DT_record * u, DT_record * v, edge_type etype, graph_type gtype);

这似乎是所有事物的“黄金”方法,并且根据 etype 和 gtype 的值会对图执行不同的操作。

太好了,根据您的经验和知识,您有什么建议?

顺便说一句,我相信以前有人问过这个问题,因为这是我的实现。

【问题讨论】:

  • 你的缩进看起来有点随意。

标签: algorithm data-structures graph


【解决方案1】:

遗憾的是,这是普通的 C。使用 C++,其中几个问题将由语言的多态特性来处理。另一方面,以这种方式学习算法会让你专注于算法/数据结构,而不是语言的一些巧妙特性。

无论如何...我的两分钱:

关于选择 d 或 u 图形类型:为什么不向 DT_Graph 添加一个属性来通知调用的图形类型的方法。毕竟,这是在创建图表时指定的。 ==> 砰!我们只剩下 2 种方法。

关于边缘权重...也许有两种方法更可取,API 方面:为什么要用额外的参数来打扰非加权的情况。在实现方面,您当然可以在所有 4 个案例之间共享尽可能多的逻辑。坦率地说,一旦你编写了所有这些,你仍然可以将这些隐藏在一个单一的“黄金”方法后面,就像你建议的那样。

祝你的编码好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 2011-04-27
    • 2012-05-26
    • 1970-01-01
    • 2012-10-06
    • 2014-12-20
    相关资源
    最近更新 更多