AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 76985913
Accepted
VIAGC
VIAGC
Asked: 2023-08-27 14:18:10 +0800 CST2023-08-27 14:18:10 +0800 CST 2023-08-27 14:18:10 +0800 CST

Criando um gráfico usando lista de adjacências

  • 772

Estou seguindo o Manual de Design de Algoritmo v3 da Skiena.

Tenho visto algumas perguntas afirmando que há certos erros de digitação no livro e não tenho certeza se é um deles ou apenas porque não consigo entendê-los.

Considere o seguinte:

typedef struct edgenode {
    int y;                   /* adjacency info */
    int weight;              /* edge weight, if any */
    struct edgenode *next;   /* next edge in list */
} edgenode;

typedef struct {
    edgenode *edges[MAXV+1];  /* adjacency info */
    int degree[MAXV+1];       /* outdegree of each vertex */
    int nvertices;            /* number of vertices in the graph */
    int nedges;               /* number of edges in the graph */
    int directed;             /* is the graph directed? */
} graph;

void insert_edge(graph *g, int x, int y, bool directed) {
    edgenode *p;        /* temporary pointer */

    p = malloc(sizeof(edgenode));    /* allocate edgenode storage */

    p->weight = 0;
    p->y = y;
    p->next = g->edges[x];

    g->edges[x] = p;    /* insert at head of list */

    g->degree[x]++;

    if (!directed) {
        insert_edge(g, y, x, true);
    } else {
        g->nedges++;
    }
}

Pelo que entendi, void insert_edge(graph *g, int x, int y, bool directed)conecta dois nós no índice do array xe yos adiciona ao edgesarray.

O seguinte trecho me confunde:

p->y = y;
p->next = g->edges[x];

g->edges[x] = p;    /* insert at head of list */

Como isso está funcionando? Suponha que minha entrada seja x = 3, y = 4e esta seja a primeira entrada.

Eu esperaria algo parecido 3 -> 4com um gráfico direcionado.

  1. p->y = y;faz todo o sentido, o adjacente de xé y.
  2. p->next = g->edges[x];Mas a edgesmatriz é inicializada como nula. Isso não fará 3.next == NULLem vez de 3.next == 4?
  3. g->edges[x] = p;O que? edges[x] == x Node, isso me confunde.

O código completo pode ser encontrado em graph.c e graph.h .

Acho que p.next = y;de alguma forma e y.next = NULLa partir de agora, ou seja, a primeira inserção. Talvez seja meu C enferrujado, mas preciso de ajuda nisso.

c
  • 1 1 respostas
  • 52 Views

1 respostas

  • Voted
  1. Best Answer
    trincot
    2023-08-27T18:46:26+08:002023-08-27T18:46:26+08:00

    Pelo que entendi, insert_edgeconecta dois nós no índice da matriz x e y adicionando-os à edgesmatriz.

    Eu não chamaria isso de "adicionar ao edgesarray", já que o edgesarray tem um comprimento fixo e uma entrada para cada nó (não para cada edge ).

    O índice de edgesidentifica o vértice "de" de uma aresta, e o ycampo de edgenodeidentifica o vértice "para" correspondente dessa mesma aresta.

    Para cada vértice x, este código mantém uma lista vinculada de arestas (não edges, mas edges[x]), que inicialmente estará vazia.

    Vamos fazer isso para um gráfico de exemplo:

    insira a descrição da imagem aqui

    ...que após a inicialização é preenchido com suas arestas da seguinte forma:

    insert_edge(g, 0, 1, true); 
    insert_edge(g, 0, 2, true); 
    insert_edge(g, 1, 2, true); 
    insert_edge(g, 2, 3, true); 
    insert_edge(g, 3, 4, true); 
    

    Vamos ver como isso preenche a graphestrutura de dados. Começamos com este estado para g(onde assumirei MAXVque é 4 para esta representação):

        ┌───────────┬────┬────┬────┬────┬────┐    
    g ─►│ edges     │  - │  - │  - │  - │  - │
        ├───────────┼────┼────┼────┼────┼────┤
        │ degree    │  0 │  0 │  0 │  0 │  0 │
        ├───────────┼────┼────┴────┴────┴────┘
        │ nvertices │  5 │ 
        ├───────────┼────┤
        │ nedges    │  0 │
        ├───────────┼────┤
        │ directed  │true│
        └───────────┴────┘
    

    Os hífens representam nullpointervalores. Presumo que tudo isso foi inicializado corretamente.

    Em seguida, insert_edge(g, 0, 1, true)criaremos um pnó, que será alocado e inicializado para isto:

        ┌────────┬────┐
    p ─►│ weight │  0 │
        ├────────┼────┤
        │ y      │  1 │
        ├────────┼────┤
        │ next   │  - │
        └────────┴────┘
    

    Notavelmente, o nextcampo é nullptr, porque esse é o valor encontrado em g->edges[0].

    Em seguida, a próxima instrução g->edges[x] = pfaz a ligação e, após dois contadores terem sido incrementados, a função concluiu seu trabalho:

                          ┌────────┬────┐
                      p ─►│ weight │  0 │
                          ├────────┼────┤
                          │ y      │  1 │
                          ├────────┼────┤
                       ┌─►│ next   │  - │
                       │  └────────┴────┘
                       │
                       │
                       │
                       │
        ┌───────────┬──│─┬────┬────┬────┬────┐    
    g ─►│ edges     │  ┴ │  - │  - │  - │  - │
        ├───────────┼────┼────┼────┼────┼────┤
        │ degree    │  1 │  0 │  0 │  0 │  0 │
        ├───────────┼────┼────┴────┴────┴────┘
        │ nvertices │  5 │ 
        ├───────────┼────┤
        │ nedges    │  1 │
        ├───────────┼────┤
        │ directed  │true│
        └───────────┴────┘
    

    Agora chegamos ao mais interessante: insert_edge(g, 0, 2, true);. Novamente pé apontado para um novo edgenode, mas desta vez g->edges[0]não é nullptre então p->nextapontaremos para o adicionado anteriormente edgenode. Depois de insert_edgeterminar, obtemos isto:

                          ┌────────┬────┐  ┌────────┬────┐
                      p ─►│ weight │  0 │  │ weight │  0 │
                          ├────────┼────┤  ├────────┼────┤
                          │ y      │  2 │  │ y      │  1 │
                          ├────────┼────┤  ├────────┼────┤
                       ┌─►│ next   │  ────►│ next   │  - │
                       │  └────────┴────┘  └────────┴────┘
                       │
                       │
                       │
                       │
        ┌───────────┬──│─┬────┬────┬────┬────┐    
    g ─►│ edges     │  ┴ │  - │  - │  - │  - │
        ├───────────┼────┼────┼────┼────┼────┤
        │ degree    │  2 │  0 │  0 │  0 │  0 │
        ├───────────┼────┼────┴────┴────┴────┘
        │ nvertices │  5 │ 
        ├───────────┼────┤
        │ nedges    │  2 │
        ├───────────┼────┤
        │ directed  │true│
        └───────────┴────┘
    

    E assim continua para as outras arestas: toda vez que o new edgenodeé anexado a uma lista vinculada da qual o ponteiro principal está armazenado no edgesarray. Temos 5 listas vinculadas: uma para cada vértice.

    Aqui está o resultado final do exemplo acima:

                          ┌────────┬────┐  ┌────────┬────┐
                          │ weight │  0 │  │ weight │  0 │
                          ├────────┼────┤  ├────────┼────┤
                          │ y      │  2 │  │ y      │  1 │
                          ├────────┼────┤  ├────────┼────┤
                       ┌─►│ next   │  ────►│ next   │  - │
                       │  └────────┴────┘  └────────┴────┘
                       │       ┌────────┬────┐  ┌────────┬────┐
                       │       │ weight │  0 │  │ weight │  0 │
                       │       ├────────┼────┤  ├────────┼────┤
                       │       │ y      │  4 │  │ y      │  2 │
                       │       ├────────┼────┤  ├────────┼────┤
                       │    ┌─►│ next   │  ────►│ next   │  - │
                       │    │  └────────┴────┘  └────────┴────┘
                       │    │       ┌────────┬────┐
                       │    │       │ weight │  0 │
                       │    │       ├────────┼────┤
                       │    │       │ y      │  3 │
                       │    │       ├────────┼────┤
                       │    │    ┌─►│ next   │  - │
                       │    │    │  └────────┴────┘
                       │    │    │       ┌────────┬────┐
                       │    │    │       │ weight │  0 │
                       │    │    │       ├────────┼────┤
                       │    │    │       │ y      │  4 │
                       │    │    │       ├────────┼────┤
                       │    │    │    ┌─►│ next   │  - │
                       │    │    │    │  └────────┴────┘
        ┌───────────┬──│─┬──│─┬──│─┬──│─┬────┐    
    g ─►│ edges     │  ┴ │  ┴ │  ┴ │  ┴ │  - │
        ├───────────┼────┼────┼────┼────┼────┤
        │ degree    │  2 │  2 │  1 │  1 │  0 │
        ├───────────┼────┼────┴────┴────┴────┘
        │ nvertices │  5 │ 
        ├───────────┼────┤
        │ nedges    │  6 │
        ├───────────┼────┤
        │ directed  │true│
        └───────────┴────┘
    

    Espero que isso esclareça.

    • 2

relate perguntas

  • Multiplicação mais rápida que *

  • Usando uma macro para comprimento de string no especificador de formato scanf () em C

  • Como você pode definir o tipo de dados de #define para long double?

  • Ponteiros const incompatíveis

  • Mudança de cor não gradual no OpenGL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve