Это действительно зависит от того, какие алгоритмы вам нужно реализовать, серебряной пули нет (и это не должно удивлять ... общее правило программирования - отсутствие общего правила ;-)).
Я часто заканчиваю тем, что представляю направленные мультиграфы, используя структуры узлов / ребер с указателями ... более конкретно:
struct Node
{
... payload ...
Link *first_in, *last_in, *first_out, *last_out;
};
struct Link
{
... payload ...
Node *from, *to;
Link *prev_same_from, *next_same_from,
*prev_same_to, *next_same_to;
};
Другими словами, каждый узел имеет двунаправленный список входящих ссылок и двояко-связанный список исходящих ссылок.Каждая ссылка знает узлы from
и to
и одновременно находится в двух разных двусвязных списках: список всех ссылок, исходящих из одного узла from
, и список всех ссылок, приходящих в один и тот же to
узел.
Указатели prev_same_from
и next_same_from
используются при следовании по цепочке всех ссылок, выходящих из одного и того же узла;указатели prev_same_to
и next_same_to
вместо этого используются при управлении цепочкой всех ссылок, указывающих на один и тот же узел.
Сильно вертятся указатели (поэтому, если вы не любите указатели, просто забудьте об этом), но операции запроса и обновления эффективны;например, добавление узла или ссылки - это O (1), удаление ссылки - это O (1), а удаление узла x - это O (deg (x)).
Конечно, в зависимости от проблемы, полезная нагрузкаразмер, размер графика, плотность графика. Этот подход может быть слишком излишним или слишком требовательным к памяти (помимо полезной нагрузки у вас есть 4 указателя на узел и 6 указателей на ссылку).
Полная реализация аналогичной структуры можетможно найти здесь .