Files
hello-algo/ru/docs/chapter_graph/graph_operations.md
T
Yudong Jin 772183705e Add ru version (#1865)
* Add Russian docs site baseline

* Add Russian localized codebase

* Polish Russian code wording

* Update ru code translation.

* Update code translation and chapter covers.

* Fix pythontutor extraction.

* Add README and landing page.

* placeholder of profiles

* Use figures of English version

* Remove chapter paperbook
2026-03-28 04:24:07 +08:00

9.6 KiB

Базовые операции графа

Базовые операции графа можно разделить на операции над "ребрами" и операции над "вершинами". В двух способах представления - "матрица смежности" и "список смежности" - реализация будет различаться.

Реализация на основе матрицы смежности

Пусть дан неориентированный граф с числом вершин n . Тогда способы реализации различных операций показаны на рисунках ниже.

  • Добавление или удаление ребра: достаточно изменить соответствующее ребро в матрице смежности, это требует O(1) времени. Поскольку граф неориентированный, нужно одновременно обновлять ребра в обоих направлениях.
  • Добавление вершины: в конец матрицы смежности добавляется одна строка и один столбец, которые полностью заполняются нулями; это требует O(n) времени.
  • Удаление вершины: из матрицы смежности удаляется одна строка и один столбец. В худшем случае, когда удаляются первая строка и первый столбец, приходится "сдвигать вверх-влево" (n-1)^2 элементов, поэтому требуется O(n^2) времени.
  • Инициализация: передаются n вершин, затем инициализируется список вершин vertices длины n , что требует O(n) времени; после этого инициализируется матрица смежности adjMat размера n \times n , что требует O(n^2) времени.

=== "Инициализация матрицы смежности" Инициализация матрицы смежности, добавление и удаление ребер и вершин

=== "Добавление ребра" adjacency_matrix_add_edge

=== "Удаление ребра" adjacency_matrix_remove_edge

=== "Добавление вершины" adjacency_matrix_add_vertex

=== "Удаление вершины" adjacency_matrix_remove_vertex

Ниже приведен код реализации графа на основе матрицы смежности:

[file]{graph_adjacency_matrix}-[class]{graph_adj_mat}-[func]{}

Реализация на основе списка смежности

Пусть неориентированный граф содержит в сумме n вершин и m ребер. Тогда различные операции можно реализовать способом, показанным на рисунках ниже.

  • Добавление ребра: достаточно добавить ребро в конец списка, соответствующего вершине; это требует O(1) времени. Поскольку граф неориентированный, нужно одновременно добавлять ребра в обоих направлениях.
  • Удаление ребра: нужно найти и удалить указанное ребро в списке, соответствующем вершине; это требует O(m) времени. В неориентированном графе нужно удалять ребра в обоих направлениях.
  • Добавление вершины: в список смежности добавляется еще один список, а новая вершина становится его головным узлом; это требует O(1) времени.
  • Удаление вершины: требуется пройти по всему списку смежности и удалить все ребра, содержащие указанную вершину; это требует O(n + m) времени.
  • Инициализация: в списке смежности создаются n вершин и 2m ребер; это требует O(n + m) времени.

=== "Инициализация списка смежности" Инициализация списка смежности, добавление и удаление ребер и вершин

=== "Добавление ребра" adjacency_list_add_edge

=== "Удаление ребра" adjacency_list_remove_edge

=== "Добавление вершины" adjacency_list_add_vertex

=== "Удаление вершины" adjacency_list_remove_vertex

Ниже приведен код списка смежности. По сравнению с рисунками выше, реальная реализация имеет следующие отличия.

  • Чтобы упростить добавление и удаление вершин, а также упростить код, мы используем список, то есть динамический массив, вместо связного списка.
  • Для хранения списка смежности используется хеш-таблица, где key - это экземпляр вершины, а value - список смежных вершин данной вершины.

Кроме того, в списке смежности мы используем класс Vertex для представления вершины. Причина в следующем: если, как и в матрице смежности, различать вершины по индексам списка, то при удалении вершины с индексом i пришлось бы обходить весь список смежности и уменьшать на 1 все индексы, большие i , что крайне неэффективно. Если же каждая вершина является уникальным экземпляром Vertex , то после удаления одной вершины остальные вершины менять уже не требуется.

[file]{graph_adjacency_list}-[class]{graph_adj_list}-[func]{}

Сравнение эффективности

Пусть в графе имеется n вершин и m ребер. В таблице ниже сравниваются временная и пространственная эффективность матрицы смежности и списка смежности. Обрати внимание: список смежности (связный список) соответствует реализации из этой статьи, а список смежности (хеш-таблица) означает вариант, где все списки заменены хеш-таблицами.

Таблица   Сравнение матрицы смежности и списка смежности

Матрица смежности Список смежности (связный список) Список смежности (хеш-таблица)
Проверка смежности O(1) O(n) O(1)
Добавление ребра O(1) O(1) O(1)
Удаление ребра O(1) O(n) O(1)
Добавление вершины O(n) O(1) O(1)
Удаление вершины O(n^2) O(n + m) O(n)
Занимаемая память O(n^2) O(n + m) O(n + m)

Если смотреть только на таблицу, может показаться, что список смежности на основе хеш-таблицы является лучшим и по времени, и по памяти. Но на практике операции над ребрами в матрице смежности часто выполняются быстрее, потому что там нужен лишь один доступ к массиву или одно присваивание. В целом матрица смежности воплощает принцип "обмен пространства на время", а список смежности - принцип "обмен времени на пространство".