48.md 6.5 KB
Newer Older
W
wizardforcel 已提交
1 2 3 4
# 邻接表

> 原文: [https://www.programiz.com/dsa/graph-adjacency-list](https://www.programiz.com/dsa/graph-adjacency-list)

W
wizardforcel 已提交
5
#### 在本教程中,您将学习什么是邻接表。 此外,您还将在 C,C++ ,Java 和 Python 中找到邻接表的工作示例。
W
wizardforcel 已提交
6

W
wizardforcel 已提交
7
邻接列表将图表示为链表的数组。
W
wizardforcel 已提交
8 9 10 11 12 13 14 15 16 17 18

数组的索引表示一个顶点,而其链表中的每个元素表示与该顶点形成边的其他顶点。

* * *

## 邻接表表示

图及其等效的邻接表表示如下。

![Adjacency List representation](img/a0cdb21344c49353e73743f80fe28594.png "Adjacency List representation")

W
wizardforcel 已提交
19
邻接表表示
W
wizardforcel 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50



邻接表在存储方面非常有效,因为我们只需要存储边的值即可。 对于具有数百万个顶点和边的稀疏图,这可能意味着节省了大量空间。

* * *

## 邻接表结构

最简单的邻接表需要一个节点数据结构来存储顶点,并需要一个图数据结构来组织节点。

我们接近图的基本定义-顶点和边的集合`{V, E}`。 为简单起见,我们使用未标记图而不是标记图,即顶点由其索引 0、1、2、3 标识。

让我们在这里深入研究数据结构。

```
struct node
{
    int vertex;
    struct node* next;
};

struct Graph
{
    int numVertices;
    struct node** adjLists;
};
```

不要让`struct node** adjLists`淹没您。

W
wizardforcel 已提交
51
我们只是说要存储指向`struct node*`的指针。 这是因为我们不知道图形将具有多少个顶点,因此无法在编译时创建链表的数组。
W
wizardforcel 已提交
52 53 54

* * *

W
wizardforcel 已提交
55
## 邻接表 C++ 
W
wizardforcel 已提交
56

W
wizardforcel 已提交
57
它是相同的结构,但是通过使用 C++ 的内置列表 STL 数据结构,我们使该结构更整洁。 我们还能够抽象出实现的细节。
W
wizardforcel 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

```
class Graph
{
    int numVertices;
    list<int> *adjLists;

public:
    Graph(int V);
    void addEdge(int src, int dest);
};
```

* * *

## 邻接表 Java

W
wizardforcel 已提交
75
我们使用 Java 集合来存储链表数组。
W
wizardforcel 已提交
76 77 78 79 80 81 82 83 84

```
class Graph
{
    private int numVertices;
    private LinkedList<integer> adjLists[];
}
```

W
wizardforcel 已提交
85
`LinkedList`的类型由要存储在其中的数据确定。 对于带标签的图形,您可以存储字典而不是整数
W
wizardforcel 已提交
86 87 88 89 90

* * *

## 邻接表 Python

W
wizardforcel 已提交
91
Python 得到如此多的爱是有原因的。 一个简单的顶点及其边的字典就足以表示一个图。 您可以按需使顶点本身复杂。
W
wizardforcel 已提交
92 93 94 95 96 97 98 99 100 101 102 103

```
graph = {'A': set(['B', 'C']),
         'B': set(['A', 'D', 'E']),
         'C': set(['A', 'F']),
         'D': set(['B']),
         'E': set(['B', 'F']),
         'F': set(['C', 'E'])}
```

* * *

W
wizardforcel 已提交
104
## Python,Java 和 C/C++ 示例
W
wizardforcel 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

[Python](#python-code)[Java](#java-code)[C](#c-code)[C++](#cpp-code)

```
# Adjascency List representation in Python

class AdjNode:
    def __init__(self, value):
        self.vertex = value
        self.next = None

class Graph:
    def __init__(self, num):
        self.V = num
        self.graph = [None] * self.V

    # Add edges
    def add_edge(self, s, d):
        node = AdjNode(d)
        node.next = self.graph[s]
        self.graph[s] = node

        node = AdjNode(s)
        node.next = self.graph[d]
        self.graph[d] = node

    # Print the graph
    def print_agraph(self):
        for i in range(self.V):
            print("Vertex " + str(i) + ":", end="")
            temp = self.graph[i]
            while temp:
                print(" -> {}".format(temp.vertex), end="")
                temp = temp.next
            print(" \n")

if __name__ == "__main__":
    V = 5

    # Create graph and edges
    graph = Graph(V)
    graph.add_edge(0, 1)
    graph.add_edge(0, 2)
    graph.add_edge(0, 3)
    graph.add_edge(1, 2)

    graph.print_agraph()
```

```
// Adjascency List representation in Java

import java.util.*;

class Graph {

  // Add edge
  static void addEdge(ArrayList<ArrayList<Integer>> am, int s, int d) {
    am.get(s).add(d);
    am.get(d).add(s);
  }

  public static void main(String[] args) {

    // Create the graph
    int V = 5;
    ArrayList<ArrayList<Integer>> am = new ArrayList<ArrayList<Integer>>(V);

    for (int i = 0; i < V; i++)
      am.add(new ArrayList<Integer>());

    // Add edges
    addEdge(am, 0, 1);
    addEdge(am, 0, 2);
    addEdge(am, 0, 3);
    addEdge(am, 1, 2);

    printGraph(am);
  }

  // Print the graph
  static void printGraph(ArrayList<ArrayList<Integer>> am) {
    for (int i = 0; i < am.size(); i++) {
      System.out.println("\nVertex " + i + ":");
      for (int j = 0; j < am.get(i).size(); j++) {
        System.out.print(" -> " + am.get(i).get(j));
      }
      System.out.println();
    }
  }
}
```

```
// Adjascency List representation in C

#include <stdio.h>
#include <stdlib.h>

struct node {
  int vertex;
  struct node* next;
};
struct node* createNode(int);

struct Graph {
  int numVertices;
  struct node** adjLists;
};

// Create a node
struct node* createNode(int v) {
  struct node* newNode = malloc(sizeof(struct node));
  newNode->vertex = v;
  newNode->next = NULL;
  return newNode;
}

// Create a graph
struct Graph* createAGraph(int vertices) {
  struct Graph* graph = malloc(sizeof(struct Graph));
  graph->numVertices = vertices;

  graph->adjLists = malloc(vertices * sizeof(struct node*));

  int i;
  for (i = 0; i < vertices; i++)
    graph->adjLists[i] = NULL;

  return graph;
}

// Add edge
void addEdge(struct Graph* graph, int s, int d) {
  // Add edge from s to d
  struct node* newNode = createNode(d);
  newNode->next = graph->adjLists[s];
  graph->adjLists[s] = newNode;

  // Add edge from d to s
  newNode = createNode(s);
  newNode->next = graph->adjLists[d];
  graph->adjLists[d] = newNode;
}

// Print the graph
void printGraph(struct Graph* graph) {
  int v;
  for (v = 0; v < graph->numVertices; v++) {
    struct node* temp = graph->adjLists[v];
    printf("\n Vertex %d\n: ", v);
    while (temp) {
      printf("%d -> ", temp->vertex);
      temp = temp->next;
    }
    printf("\n");
  }
}

int main() {
  struct Graph* graph = createAGraph(4);
  addEdge(graph, 0, 1);
  addEdge(graph, 0, 2);
  addEdge(graph, 0, 3);
  addEdge(graph, 1, 2);

  printGraph(graph);

  return 0;
}
```

```
// Adjascency List representation in C++

#include <bits/stdc++.h>
using namespace std;

// Add edge
void addEdge(vector<int> adj[], int s, int d) {
  adj[s].push_back(d);
  adj[d].push_back(s);
}

// Print the graph
void printGraph(vector<int> adj[], int V) {
  for (int d = 0; d < V; ++d) {
    cout << "\n Vertex "
       << d << ":";
    for (auto x : adj[d])
      cout << "-> " << x;
    printf("\n");
  }
}

int main() {
  int V = 5;

  // Create a graph
  vector<int> adj[V];

  // Add edges
  addEdge(adj, 0, 1);
  addEdge(adj, 0, 2);
  addEdge(adj, 0, 3);
  addEdge(adj, 1, 2);
  printGraph(adj, V);
}
```