首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >邻接表从零开始

邻接表从零开始
EN

Code Review用户
提问于 2016-11-22 18:50:32
回答 2查看 281关注 0票数 0

这是我从零开始实现邻接列表的代码。我想从专家那里得到优化的反馈。

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


 /*a single node of an adjacency list*/
typedef struct adjList{

    int dest;
    struct adjList *next;

} adjList;


/*Image of a graph...*/

typedef struct Image{

    int source;
    adjList *head;

} Image;



void initialize_graph(Image *graph, int vertices);

void print_graph(Image graph[], int vertices);

void add_adj_node(Image *graph, int source, int destiny, bool directed);

void free_graph(Image graph[], int vertices);



int main() {

    int vertices;
    scanf("%d", &vertices);


    Image graph[vertices];

    printf("size of graph: %d bytes\n", sizeof graph);


    initialize_graph(graph, vertices);

    printf("initialized image of graph\n");

    print_graph(graph, vertices);

    printf("                          \n");
    //is the graph directed ? ans: false

    add_adj_node(graph, 1, 7, false);
    add_adj_node(graph, 1, 3, false);
    add_adj_node(graph, 4, 6, false);
    add_adj_node(graph, 4, 1, false);
    add_adj_node(graph, 5, 2, false);
    add_adj_node(graph, 1, 5, false);
    add_adj_node(graph, 1, 2, false);

    print_graph(graph, vertices);

    free_graph(graph, vertices);

    /*if this print produces segmentation fault then the memory is fully freed*/
    printf("graph[1].head->dest%d\n", graph[1].head->dest);


    return 0;
}




void initialize_graph(Image graph[], int vertices) {


        for(int i = 1; i<= vertices; i++){
                graph[i].source = i;
                graph[i].head = NULL;
        }

        return;
}



void add_adj_node(Image *graph, int src, int dest, bool directed){

    adjList *cache = malloc(sizeof(adjList));
    /*create a single node*/
    cache->dest = dest;
    cache->next = NULL;


    if(graph[src].head == NULL){
            graph[src].head = cache;

    }


    else{
            /*put the head address on the crawler*/
            adjList *crawler = graph[src].head;

            while( crawler->next != NULL){
                crawler = crawler->next;
            }

            /*update head value and address. head will point to new adj node
             this will also link src -> dest*/

            crawler->next = cache;
    }




    if (directed == false) {
          directed = true; 

          /*notice we've changed the sequence. dest and src*/
          add_adj_node( graph, dest, src, directed);
    }

    return;
}



void print_graph(Image *graph, int vertices){

    for(int i = 1; i<= vertices; i++){

                adjList *crawl = graph[i].head;
                printf("node: %d    ", graph[i].source);

                while(crawl){

                      printf("%d ", crawl->dest);
                      crawl = crawl->next;
                }

                printf("\n");
        }

    return;
}


/*just a reverse version of crawling a graph*/

void free_graph(Image *graph, int vertices){

    for(int i = 1; i<= vertices; i++){

                adjList *cache;
                printf("releasing elements of node: %d    ", graph[i].source);

                while(graph[i].head){

                      /*put the next adjacency node in the cache*/
                      cache = graph[i].head->next;
                      /*free the present adjacencey node*/
                      free(graph[i].head);
                      graph[i].head = cache;
                }

                printf("\n");
        }

    return;
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2016-11-22 19:46:17

  • 超出范围的访问:数组图像图顶点;有vertices条目,从索引0开始,最大的有效索引是vertices - 1。用于(int= 1;i<=顶点;i++)的循环接触到graph[vertices],这是非法的。一个正确的(和白痴的)循环用于(int= 0;i<顶点;i++)
  • 通过诱导分段故障来正确释放内存的测试,可以说是非常规的。你甚至不能保证得到一个。
  • 爬上名单是在浪费时间。将新创建的节点放在列表的最前面要简单得多: void add_adj_node(图像*图,int,int,int,bool有向){ adjList *节点= create_node( dest );节点->next=图src.head;图src head = node };
  • 递归调用add_adj_node是令人困惑的。我建议有一个辅助函数do_add_adj_node,并像这样调用它: void add_adj_node(图像*图,int src,int add_adj_node){do_add_adj_node(图,src,dst);do_add_adj_node(图,dst,src)};
票数 2
EN

Code Review用户

发布于 2016-11-22 20:47:53

有这么多空白行,看看你怎么会滚动这么多才能读到代码!

为了将函数中的语句组分开,或者用一两行空行分隔函数,偶尔使用空行是可以的。但在我看来,两行以上的空白处是不必要的。

下面是我将如何呈现代码。除了删除46行空白行之外,我什么也没有改变,这大约是所有原始行的四分之一!

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


 /*a single node of an adjacency list*/
typedef struct adjList{
    int dest;
    struct adjList *next;
} adjList;


/*Image of a graph...*/
typedef struct Image{
    int source;
    adjList *head;
} Image;


void initialize_graph(Image *graph, int vertices);
void print_graph(Image graph[], int vertices);
void add_adj_node(Image *graph, int source, int destiny, bool directed);
void free_graph(Image graph[], int vertices);


int main() {
    int vertices;
    scanf("%d", &vertices);

    Image graph[vertices];
    printf("size of graph: %d bytes\n", sizeof graph);

    initialize_graph(graph, vertices);
    printf("initialized image of graph\n");

    print_graph(graph, vertices);
    printf("                          \n");
    //is the graph directed ? ans: false

    add_adj_node(graph, 1, 7, false);
    add_adj_node(graph, 1, 3, false);
    add_adj_node(graph, 4, 6, false);
    add_adj_node(graph, 4, 1, false);
    add_adj_node(graph, 5, 2, false);
    add_adj_node(graph, 1, 5, false);
    add_adj_node(graph, 1, 2, false);

    print_graph(graph, vertices);

    free_graph(graph, vertices);

    /*if this print produces segmentation fault then the memory is fully freed*/
    printf("graph[1].head->dest%d\n", graph[1].head->dest);

    return 0;
}


void initialize_graph(Image graph[], int vertices) {
        for(int i = 1; i<= vertices; i++){
                graph[i].source = i;
                graph[i].head = NULL;
        }

        return;
}


void add_adj_node(Image *graph, int src, int dest, bool directed){
    adjList *cache = malloc(sizeof(adjList));
    /*create a single node*/
    cache->dest = dest;
    cache->next = NULL;

    if(graph[src].head == NULL){
            graph[src].head = cache;
    }
    else{
            /*put the head address on the crawler*/
            adjList *crawler = graph[src].head;

            while( crawler->next != NULL){
                crawler = crawler->next;
            }
            /*update head value and address. head will point to new adj node
             this will also link src -> dest*/
            crawler->next = cache;
    }

    if (directed == false) {
          directed = true; 
          /*notice we've changed the sequence. dest and src*/
          add_adj_node( graph, dest, src, directed);
    }

    return;
}


void print_graph(Image *graph, int vertices){
    for(int i = 1; i<= vertices; i++){
                adjList *crawl = graph[i].head;
                printf("node: %d    ", graph[i].source);

                while(crawl){
                      printf("%d ", crawl->dest);
                      crawl = crawl->next;
                }
                printf("\n");
        }

    return;
}


/*just a reverse version of crawling a graph*/
void free_graph(Image *graph, int vertices){
    for(int i = 1; i<= vertices; i++){
                adjList *cache;
                printf("releasing elements of node: %d    ", graph[i].source);

                while(graph[i].head){
                      /*put the next adjacency node in the cache*/
                      cache = graph[i].head->next;
                      /*free the present adjacencey node*/
                      free(graph[i].head);
                      graph[i].head = cache;
                }
                printf("\n");
        }

    return;
}
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/147816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档