Перейти к содержанию

9.1   Граф

Граф (graph) - это нелинейная структура данных, состоящая из вершин (vertex) и ребер (edge). Мы можем абстрактно представить граф \(G\) как множество вершин \(V\) и множество ребер \(E\) . В примере ниже показан граф, содержащий 5 вершин и 7 ребер.

\[ \begin{aligned} V & = \{ 1, 2, 3, 4, 5 \} \newline E & = \{ (1,2), (1,3), (1,5), (2,3), (2,4), (2,5), (4,5) \} \newline G & = \{ V, E \} \newline \end{aligned} \]

Если рассматривать вершины как узлы, а ребра как ссылки (указатели), соединяющие эти узлы, то граф можно считать структурой данных, выросшей из связного списка. Как показано на рисунке 9-1, по сравнению с линейными отношениями (связный список) и отношениями разделения (дерево), сетевые отношения (граф) обладают большей свободой , а потому и сложнее.

Связь между связным списком, деревом и графом

Рисунок 9-1   Связь между связным списком, деревом и графом

9.1.1   Распространенные типы и термины графов

В зависимости от того, имеют ли ребра направление, графы делятся на неориентированные графы (undirected graph) и ориентированные графы (directed graph) , как показано на рисунке 9-2.

  • В неориентированном графе ребро означает "двустороннюю" связь между двумя вершинами, например отношение "друзья" в WeChat или QQ.
  • В ориентированном графе ребро имеет направление, то есть ребра \(A \rightarrow B\) и \(A \leftarrow B\) независимы друг от друга, как, например, отношения "подписка" и "подписчик" в Weibo или Douyin.

Ориентированный и неориентированный графы

Рисунок 9-2   Ориентированный и неориентированный графы

В зависимости от того, достижимы ли все вершины друг из друга, граф делится на связный граф (connected graph) и несвязный граф (disconnected graph) , как показано на рисунке 9-3.

  • В связном графе, начиная из некоторой вершины, можно добраться до любой другой вершины.
  • В несвязном графе, начиная из некоторой вершины, по крайней мере одна вершина оказывается недостижимой.

Связный и несвязный графы

Рисунок 9-3   Связный и несвязный графы

Мы также можем добавить к ребрам переменную "вес" и тем самым получить взвешенный граф (weighted graph) , показанный на рисунке 9-4. Например, в мобильных играх вроде Honor of Kings система может вычислять "степень близости" между игроками по времени, проведенному в совместных играх; такую сеть близости можно описать взвешенным графом.

Взвешенный и невзвешенный графы

Рисунок 9-4   Взвешенный и невзвешенный графы

Для структуры данных "граф" используются следующие распространенные термины.

  • Смежность (adjacency): если между двумя вершинами существует ребро, то эти вершины называются "смежными". На рисунке 9-4 вершинам 2, 3, 5 смежна вершина 1.
  • Путь (path): последовательность ребер, ведущая из вершины A в вершину B, называется "путем" от A до B. На рисунке 9-4 последовательность ребер 1-5-2-4 представляет один из путей от вершины 1 к вершине 4.
  • Степень (degree): число ребер, принадлежащих вершине. Для ориентированного графа входящая степень (in-degree) показывает число ребер, ведущих в вершину, а исходящая степень (out-degree) показывает число ребер, исходящих из вершины.

9.1.2   Представление графа

Распространенные способы представления графа включают "матрицу смежности" и "список смежности". Ниже в качестве примера используется неориентированный граф.

1.   Матрица смежности

Пусть число вершин графа равно \(n\) ; тогда матрица смежности (adjacency matrix) использует матрицу размера \(n \times n\) для представления графа: каждая строка и каждый столбец соответствуют вершине, а элементы матрицы отражают наличие ребра, то есть показывают, существует между двумя вершинами связь или нет.

Как показано на рисунке 9-5, пусть матрица смежности обозначается как \(M\) , а список вершин - как \(V\) ; тогда элемент матрицы \(M[i, j] = 1\) означает, что между вершинами \(V[i]\) и \(V[j]\) существует ребро, а элемент \(M[i, j] = 0\) означает, что ребра между ними нет.

Представление графа матрицей смежности

Рисунок 9-5   Представление графа матрицей смежности

Матрица смежности обладает следующими особенностями.

  • В простом графе вершина не может соединяться сама с собой, поэтому элементы на главной диагонали матрицы смежности не имеют смысла.
  • Для неориентированного графа ребра в двух направлениях эквивалентны, поэтому матрица смежности симметрична относительно главной диагонали.
  • Если заменить в матрице смежности значения \(1\) и \(0\) на веса, то можно представить и взвешенный граф.

При представлении графа матрицей смежности мы можем напрямую обращаться к элементам матрицы, чтобы получить информацию о ребрах, поэтому операции добавления, удаления, поиска и изменения обладают высокой эффективностью, равной \(O(1)\) . Однако пространственная сложность матрицы равна \(O(n^2)\) , поэтому она занимает заметный объем памяти.

2.   Список смежности

Список смежности (adjacency list) использует \(n\) связанных списков для представления графа, где узлы списка обозначают вершины. \(i\)-й список соответствует вершине \(i\) и хранит все вершины, смежные с ней, то есть все вершины, соединенные с этой вершиной. На рисунке 9-6 показан пример графа, представленного списком смежности.

Представление графа списком смежности

Рисунок 9-6   Представление графа списком смежности

Список смежности хранит только реально существующие ребра, а общее число ребер обычно значительно меньше \(n^2\) , поэтому этот способ существенно экономит пространство. Однако для поиска ребра в списке смежности нужно проходить по списку, поэтому по времени он уступает матрице смежности.

Если посмотреть на рисунок 9-6, можно заметить, что структура списка смежности очень похожа на "метод цепочек" в хеш-таблице, поэтому для оптимизации эффективности здесь можно использовать сходные идеи. Например, когда список становится слишком длинным, его можно преобразовать в AVL-дерево или красно-черное дерево, чтобы улучшить временную сложность с \(O(n)\) до \(O(\log n)\) ; можно также превратить его в хеш-таблицу и снизить сложность до \(O(1)\) .

9.1.3   Типичные применения графов

Как показано в таблице 9-1, многие реальные системы можно моделировать графами, а соответствующие задачи затем сводить к задачам вычислений на графах.

Таблица 9-1   Распространенные графы в реальной жизни

Вершина Ребро Задача вычислений на графе
Социальные сети Пользователь Дружеская связь Рекомендация потенциальных друзей
Линии метро Станция Связность между станциями Рекомендация кратчайшего маршрута
Солнечная система Небесное тело Гравитационное взаимодействие между телами Вычисление орбит планет
Оставляйте свои идеи, вопросы и предложения в комментариях