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

Я пытаюсь представить график в Adjacency List с помощью С#, как в приведенном ниже коде. Но я хотел бы знать, где можно найти лучшую реализацию на C#. Нравится этот веб-сайт для Java: http://algs4.cs.princeton.edu/41undirected/Graph.java.html

Чтобы улучшить эту реализацию, у меня есть вопрос:

  1. Есть ли другая простая структура данных, которую можно использовать и которую можно упростить, например, DFS, BFS, Find the Shortest-path? Или структура данных слишком сильно различается в зависимости от решаемой проблемы?

=== ИЗМЕНЕНО ===

Я попытался реализовать структуру данных, как показано ниже.

OBS: этот подход кажется простым, но позже я понимаю, что он не очень подходит, например, для DFS, поскольку вам нужно все время отслеживать первый элемент LinkedList. В моем решении Кажется, лучше использовать созданный пользователем связанный список вместо LinkedList<Vertex>.

Учитывая комментарии ниже и для простоты, я внес некоторые изменения. Но я не знаю, повлияют ли эти изменения на дальнейшие операции, такие как BFS. Чтобы иметь возможность иметь прямой и косвенный график, я думаю, лучше использовать интерфейс, чем свойство.

 public interface IGraph
    {
        void InsertEdge(int edgeAKey, int edgeBKey);
        void IsertNewVertex(int vertexKey);
        LinkedList<Vertex> FindByKey(int vertexKey);
        bool ExistKey(int vertexKey);
    }

Чтобы сделать это максимально простым, мы можем использовать уже реализованные структуры данных, такие как Dictionary и LinkedList. И вместо того, чтобы использовать object как Dictionary key, для простоты мы можем создать в Vertex key (или label) и value, если вы хотите добавить значение, которое уже существует в другом Vertex.

public class GraphDirect : IGraph
    {
        private Dictionary<int,LinkedList<Vertex>> Vertexes { get; set; }

        public GraphDirect()
        {
            Vertexes = new Dictionary<int, LinkedList<Vertex>>();
        }

        public bool ExistKey(int vertexKey)
        {
            if (this.FindByKey(vertexKey) == null)
                return false;
            else
                return true;
        }

        public void IsertNewVertex(int vertexKey)
        {
            if (!this.ExistKey(vertexKey))
            {
                Vertex vertex = new Vertex(vertexKey);
                LinkedList<Vertex> listVertexes = new LinkedList<Vertex>();
                listVertexes.AddFirst(vertex);
                this.Vertexes.Add(vertexKey, listVertexes);
            }
        }

        public void InsertEdge(int vertexAKey, int vertexBKey)
        {
            //Create the vertex A, if it doesn't exist            
            if (!this.ExistKey(vertexAKey))
            {
                this.IsertNewVertex(vertexAKey);
            } 
            //Will always insert the vertex B on this edge
            this.FindByKey(vertexAKey).AddLast(new Vertex(vertexBKey));
            //Create the vertex B, if doesn't exist
            if (!this.ExistKey(vertexBKey))
            {
                this.IsertNewVertex(vertexBKey);
            }
        }

        public LinkedList<Vertex> FindByKey(int vertexKey)
        {
            if (this.Vertexes.ContainsKey(vertexKey))
                return this.Vertexes[vertexKey];

            return null;
        }

    }

Классу Vertex не нужны никакие другие указатели, просто сохраните key и value, если это необходимо.

public enum State { Visited = 0, UnVisited = 1, Processed = 2 }

public class Vertex
{
    public int Key;
    public int Value;
    public State Status = State.UnVisited;

    public Vertex(int key)
    {
        this.Key = key;
        this.Value = 0;
    }

    public Vertex(int key, int value)
    {
        this.Key = key;
        this.Value = value;
    }
}

public class Start
{
     public static void Main(){
         GraphDirect gDirect = new GraphDirect();
         gDirect.InsertEdge(2, 3);
         gDirect.InsertEdge(2, 8);
         gDirect.InsertEdge(5, 6);
     }
}

person Tito    schedule 11.12.2012    source источник
comment
Если вы собираетесь использовать Vertex в качестве ключа словаря, вам необходимо реализовать его переопределения Equals и GetHashCode; это, вероятно, решит проблему с дублирующимся ключом. РЕДАКТИРОВАТЬ: Хотя в остальном не уверен. FindByValue немедленно запускает предупреждающие сирены, видя, что он перебирает словарь, а не ищет его по какому-то идентификатору.   -  person Chris Sinclair    schedule 11.12.2012
comment
@ChrisSinclair Спасибо, что сообщили мне об этом, я просто внесу некоторые изменения и обновлю свой вопрос.   -  person Tito    schedule 11.12.2012
comment
Старый вопрос, но я лично нашел этот ресурс очень полезным для всего, что связано с алгоритмом графа. Это на java, но вы можете легко перенести на C #.   -  person ctrlplusb    schedule 20.11.2014