Я пытаюсь представить график в Adjacency List
с помощью С#, как в приведенном ниже коде. Но я хотел бы знать, где можно найти лучшую реализацию на C#. Нравится этот веб-сайт для Java: http://algs4.cs.princeton.edu/41undirected/Graph.java.html
Чтобы улучшить эту реализацию, у меня есть вопрос:
- Есть ли другая простая структура данных, которую можно использовать и которую можно упростить, например,
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);
}
}
Vertex
в качестве ключа словаря, вам необходимо реализовать его переопределенияEquals
иGetHashCode
; это, вероятно, решит проблему с дублирующимся ключом. РЕДАКТИРОВАТЬ: Хотя в остальном не уверен.FindByValue
немедленно запускает предупреждающие сирены, видя, что он перебирает словарь, а не ищет его по какому-то идентификатору. - person Chris Sinclair   schedule 11.12.2012