Graph Adjacency List C# - c#

I am fairly new to programming in C# and am currently attempting to write the generic classes Graph and GraphNode which I have included below. I understand the logistics behind the methods IsAdjacent and GetNodeByID however I am not to sure how to code these correctly in C# so I have included a small bit of psuedo code in these methods. This however is not the case with the AddEdge method. If possible could you provide me with a solution to these three methods.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Graph
{
public class GraphNode<T>
{
private T id; //data stored in graph
private LinkedList<T> adjList; //adjacency list
//constructor
public GraphNode(T id)
{
this.id = id;
adjList = new LinkedList<T>();
}
//add an edge from this node : add to to the adjacency list
public void AddEdge(GraphNode<T> to)
{
adjList.AddFirst(to.ID);
}
//set and get for ID – data stored in graph
public T ID
{
set { id = value; }
get { return id; }
}
//returns adjacency list – useful for traversal methods
public LinkedList<T> GetAdjList()
{
return adjList;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Graph
{
public class Graph<T> where T : IComparable
{
//list of GraphNodes in this graph
private LinkedList<GraphNode<T>> nodes;
//constructor - set nodes to new empty list
public Graph()
{
nodes = new LinkedList<GraphNode<T>>();
}
//only return true if the graph’s list of nodes is empty
public bool IsEmptyGraph()
{
return nodes.Count == 0;
}
//Search through list of nodes for node
//Node will be a new graphnode with the
// containing the ID to be search for
public bool ContainsGraph(GraphNode<T> node)
{
//search based on ID
foreach (GraphNode<T> n in nodes)
{
if (n.ID.CompareTo(node.ID) == 0)
return true;
}
return false;
}
//find from in list of nodes and search its adjList for to
public bool IsAdjacent(GraphNode<T> from, GraphNode<T> to)
{
foreach(GraphNode<T> n in nodes)
{
if (n.ID same as from.ID)
{ if (from.AdjList contains to.ID)
return true;
}
return false;
}
}
//add a new graphNode to list of nodes
public void AddNode(T id)
{
GraphNode<T> n = new GraphNode<T>(id);
nodes.AddFirst(n);
}
//Search through list of nodes for node with this ID
public GraphNode<T> GetNodeByID(T id)
{
foreach( GraphNode<T> n in nodes )
{
if (id = n.ID)
{
return n;
}
}
return null;
}
//find from in list of nodes (look at other methods)
//and call graphNode method to add an edge to to
//think about validation here
public void AddEdge(T from, T to)
{
}
//perform a DFS traversal starting at startID, leaving a list
//of visitied ID’s in the visited list.
}
}
Many Thanks

A couple of notes:
A few of your methods take the node "ID" rather than the node itself. Wouldn't it be easier just to use the node?
Any good reason for using LinkedList rather than List for most of these items? There's an SO discussion about this here and it's not obvious what LinkedList brings to your implementation.
With adjacency lists, your AddEdge function needs to take two inputs: your source node, and destination node, and add them to each others' adjacency lists. You already have a function AddEdge in your Node class which adds a vertex to its adjacency list. So, your code will look something like this:
public void AddEdge(GraphNode source, GraphNode destination)
{
source.AddEdge(destination);
destination.AddEdge(source);
}
For isAdjacent, I'm not clear on why you need to search the entire list of nodes. You just need to check that one node is in the others' adjacency list (which should imply vice versa assuming it's coded correctly):
public bool isAdjacent(GraphNode source, GraphNode destination)
{
if (source.AdjList.Contains(destination))
{
return true;
}
return false;
}
I haven't answered your question about GetNodeByID because of my above note - I'm not sure why it's done by ID rather than by the node itself. However, I don't see a problem with your method if you really want to do it with IDs (although it should be if (id = n.ID) rather than if (id = n.ID)).

Related

singly linked list in c# using extension method

why extension method does not return the modified node in Insertion operations.
But It Working Fine at the time of Linked list Creation.
Extension method should return the modified Node.
What is the perfect way to do this.
IS extension method good in performance
Code follows
public class Node
{
public Object Data { get; set; }
public Node NextNode { get; set; }
}
public static class ListOperations
{
public static void CreateLinkedList(this Node node, Object data)
{
if (node.Data == null)
{
node.Data = data;
}
else
{
Node newnode = new Node();
newnode.Data = data;
Node current = new Node();
current = node;
while (current.NextNode != null)
{
current = current.NextNode;
}
current.NextNode = newnode;
node = current;
}
}
public static void InsertNode(this Node node1, Object data, int position)
{
Node newnode = new Node();
newnode.Data = data;
if (position == 1)
{
newnode.NextNode = node1;
node1 = newnode;
}
}
}
class Program
{
static void Main(string[] args)
{
Node node = new Node();
//random Singly LinkedList
node.CreateLinkedList(10);
node.CreateLinkedList(11);
node.CreateLinkedList(12);
node.CreateLinkedList(13);
node.CreateLinkedList(14);
node.CreateLinkedList(15);
node.InsertNode(20, 1);// this method does not return node value what is inserted.
}
}
There are many things wrong with your code, and we can deal with them later. But let's answer your questions first. I will be a bit literal and direct, since I can't assume why you have done it the way it is done.
why extension method does not return the modified node in Insertion operations.
Since your method doesn't return anything
But It Working Fine at the time of Linked list Creation.
Yes, since that code doesn't ever modify the this Node node parameter
Extension method should return the modified Node.
Only if you actually return any data from the method!
What is the perfect way to do this.
See below
IS extension method good in performance
Extension method compared with what? Compared with member method written similarly, there should really be no performance difference in the cases relevant to your example
Perfect way to do it:
So first things first: There is no need to write an extension method here. Why wouldn't you write a regular member method? Extensions are usually done when the class you want to add the functionality is not directly available for you to edit, typically as the code belongs to a third party
Second, you don't quite seem to understand the references and how the pass-by-value works. First let me post a better code, and then explain it
public class Node {
public object Data { get; set; }
public Node NextNode { get; set; }
public Node(object data) {
Data = data;
}
public Node AppendNode(object data) {
var newNode = new Node(data);
var current = this;
while (current.NextNode != null)
current = current.NextNode;
current.NextNode = newNode;
return newNode;
}
public Node SetFirstNode(object data) {
return new Node(data) { NextNode = this };
}
}
class Program {
static void Main(string[] args) {
var linkedList = new Node(10);
linkedList.AppendNode(11);
linkedList.AppendNode(12);
linkedList.AppendNode(13);
linkedList.AppendNode(14);
linkedList.AppendNode(15);
linkedList = linkedList.SetFirstNode(20);
}
}
The important things to notice from the perspective of your main question (why the insert did not work) is that the method SetFirstNode actually returns the newly created node and in Main, we re-assign the linkedlist as such linkedList = linkedList.SetFirstNode(20);
Now, you can actually write a static method and pass by ref the linkedlist, but that is not a good practice, in my opinion. Nevertheless, the code would look like below
public static class ListOperations {
public static void InsertNode(ref Node linkedList, object data) {
linkedList = new Node(data) { NextNode = linkedList };
}
}
Among other things to notice, I am calling the node object as linkedList, CreateLinkedList as AppendNode and InsertNode as SetFirstNode on purpose, so you can understand the code better.
Below is the same code with generic argument instead of object Data and using a proper InsertNode method
public class Node<T> {
public T Data { get; set; }
public Node<T> Next { get; set; }
public override string ToString() {
return Data.ToString();
}
public Node(T data) {
Data = data;
}
public Node<T> AppendNode(T data) {
var newNode = new Node<T>(data);
var current = this;
while (current.Next != null)
current = current.Next;
current.Next = newNode;
return newNode;
}
/// <summary>
/// Inserts a new node into the linkedlist as the desired position
/// </summary>
/// <param name="position">0-based index for the final position of new node</param>
/// <param name="newNode">The newly created node containing data</param>
/// <returns>returns the first node of the linkedlist</returns>
public Node<T> InsertNode(T data, int position, out Node<T> newNode) {
var current = this;
position--;
newNode = new Node<T>(data);
if (position < 0) {
newNode.Next = current;
return newNode;
}
for (int i = 0; i < position; ++i)
current = current.Next;
newNode.Next = current.Next;
current.Next = newNode;
return this;
}
}
class Program {
static void Main(string[] args) {
var linkedList = new Node<int>(10);
linkedList.AppendNode(11);
linkedList.AppendNode(12);
linkedList.AppendNode(13);
linkedList.AppendNode(14);
linkedList.AppendNode(15);
linkedList = linkedList.InsertNode(20, 0, out var newNode);
}
}

C#, Linked List, what is the difference between the last two lines?

need to know the difference between last two lines, I tried to run both ... first one goes good and display all, but second one doesn't please answer me as fast as you can .
thanks in advance
enter code here
class node
{
public int data;
//next is a pointer
public node next;
public node(int val)
{
data = val;
}
public void print()
{
Console.WriteLine(data);
}
}
class list
{
public node head;
public string name;
public list(string n)
{
name = n;
head = new node(0);
}
public void addbegin(int newval)
{
node b = new node(newval);
b.next = head.next;
// differnce between both
head.next = b;
}
You need both of those lines for the code to work correctly as far as I can tell. b.next = head.next makes b point at whatever head was pointing at (aka the first node in the list). And then head.next = b makes head point at b. Therefore these two lines insert b at the front of the linked list.
Here is a link with some more information on linked lists

Populating a TreeView from a Tree<T> object

I need to show a Tree<T> hierarchy in a TreeView, differentiating between the tree nodes and the tree leaves.
The Tree object is constructed at run time and there is no knowledge of its depth. Not a binary tree.
This is the DataTree class:
public class TreeNode<T> : IEnumerable<TreeNode<T>>
{
public T Data { get; set; }
public TreeNode<T> Parent {get; set;}
public ICollection<TreeNode<T>> Children {get; set;}
.....
.....
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<TreeNode<T>> GetEnumerator()
{
yield return this;
foreach (var directChild in this.Children)
{
foreach (var anyChild in directChild)
yield return anyChild;
}
}
}
And this is the code to populate the TreeView:
public void CreateTreeView()
{
AttributesTreeView=new TreeView();
foreach(TreeNode<string> entry in NewAttTree)
{
if(entry.Children.Count>0)
{
int tn=AttributesTreeView.Nodes.Add(new TreeNode(entry.Data.ToString().Replace("|",string.Empty)));
foreach(TreeNode<string> str in entry.Children)
{
if(tn!=0)
{
int itn=AttributesTreeView.Nodes[tn].Nodes.Add(new TreeNode(str.Data.ToString()));
}
}
}
}
}
What you're doing here is taking one tree, and projecting each node in that tree into something else, while maintaining the structure of that tree. This is actually fairly simple. Simply create a lookup that maps each node to all of its children, and then go through each of your nodes, look up "yourself" and then add all of the children from the lookup to your new node:
var roots = new TreeNode<string>[] { }; //the original data to map
var lookup = roots.SelectMany(node => node)
.ToLookup(node => node.Parent, node => new
{
node,
UINode = new TreeNode(node.Data),
});
foreach (var pair in lookup.SelectMany(group => group))
foreach (var child in lookup[pair.node])
pair.UINode.Nodes.Add(child.UINode);
TreeView view = new TreeView();
foreach (var root in lookup[null]) //assume nodes with a null parent are roots
view.Nodes.Add(root.UINode);
I can think of three ways to load a subset of the DataTreeNode structure:
Filtering: create a new DataTreeNode structure from the old structure, excluding subtrees that contain unwanted leaf nodes. Load the result.
Add a property to DataTreeNode that represents the range of values in its subtrees' leaf nodes, like a Huffman tree. Then on load, check the property before adding a given DataTreeNode.
For each DataTreeNode create a TreeNode, but discard the TreeNode if its subtrees' leaf nodes don't match the required values.
Below is pseudocode for option 3, using a HashSet to look up the required leaf node values.
void LoadDataTreeNode(TreeView treeView, DataTreeNode<T> dataTreeNode, HashSet<T> hashSet)
{
treeView.Nodes.Clear();
LoadDataTreeNode(treeView.Nodes, dataTreeNode, hashSet);
}
bool LoadDataTreeNode(TreeNodeCollection treeNodes, DataTreeNode<T> dataTreeNode, HashSet<T> hashSet)
{
bool result = hashSet.Contains(dataTreeNode.Data);
if (result)
{
var treeNode = new TreeNode(dataTreeNode.Data.ToString());
// Use this treeNode if at least one of its subtrees contains
// the required leaf node values. Assume that all other
// subtrees will be discarded by the relevant recursive calls.
result = false;
foreach (var child in dataTreeNode.Children)
{
if (LoadDataTreeNode(treeNode.Nodes, child, hashSet))
{
result = true;
}
}
if (result)
{
treeNodes.Add(treeNode);
}
}
return result;
}
OK, got it.
TreeNode newNode=new TreeNode("SEARCH");
AttributesTreeView.Nodes.Add(newNode);
CreateTreeView(NewAttTree,newNode);
public void CreateTreeView(DataTreeNode<string> root, TreeNode parentNode)
{
foreach(DataTreeNode<string> node in root.Children)
{
try
{
TreeNode newNode=new TreeNode(node.Data.ToString());
parentNode.Nodes.Add(newNode);
CreateTreeView(node,newNode);
}
catch (System.Exception e)
{
}
}
#groverboy: thanks for the push in the right direction.
One more question which presents itself:
How can we scan the DataTree structure and populate the TreeView only with the nodes that have leaves of certain value[s]. I mean in a DFT traversal, how can we decide to add a node before visiting the leaves and deciding if and which fit the filter criteria?
#groverboy: I tried your method but it didn't work and I noticed it won't ever get past the first if clause, unless the root DataTreeNode fits the bill, otherwise it returns without iterating the data tree at all.
Here is the method I came up with, based on your code: it works, but adds the same branch multiple times and I must be blind but I cant see why; maybe another pair of eyes.
bool PopulateTreeNode(DataTreeNode<string> dataNode,TreeNode treeNodes,string filter,bool ignoreCase)
{
if(dataNode.IsLeaf)
{
if(WcMatchExtensionMethods.WcMatches(dataNode.Data,filter,ignoreCase))
{
treeNodes.Nodes.Add(new TreeNode(dataNode.Data.ToString()));
return true;
}
else
return false;
}
bool result = false;
TreeNode treeNode=new TreeNode(dataNode.Data.ToString());
foreach (DataTreeNode<string> child in dataNode.Children)
{
if(PopulateTreeNode(child,treeNode,filter,ignoreCase))
{
treeNodes.Nodes.Add(treeNode);
result = true;
}
}
return result;
}

Counting descendants in a tree

I have the following class which recurs on itself to form a tree-like data structure:
public class chartObject
{
public string name { get; set; }
public int descendants { get; set; }
public List<chartObject> children { get; set; }
}
For each object in the tree I would like to populate the descendant property with the amount objects that exist underneath it.
Example structure:
chartObject1 (descendants: 4)
└-chartObject2 (descendants: 0)
└-chartObject3 (descendants: 2)
└--chartObject4 (descendants: 1)
└---chartObject5 (descendants: 0)
What would be the most efficient way of doing this?
How about the recursive formula:
children.Count + children.Sum(c => c.descendants)
This is suitable for eager-evaluation / caching if the tree is immutable (which it isn't from the class declaration). If you want efficiency even in the face of mutability, you'll find this a lot more difficult; you can consider marking parts of the tree "dirty" as it is mutated / eagerly force the re-evalutation of this metric to "bubble up" as part of a tree is mutated.
This works for me:
public void SetDescendants(chartObject current)
{
foreach (var child in current.children)
{
SetDescendants(child);
}
current.descendants = current.children.Sum(x => 1 + x.descendants);
}
I tested with this code:
var co = new chartObject()
{
name = "chartObject1",
children = new List<chartObject>()
{
new chartObject()
{
name = "chartObject2",
children = new List<chartObject>() { }
},
new chartObject()
{
name = "chartObject3",
children = new List<chartObject>()
{
new chartObject()
{
name = "chartObject4",
children = new List<chartObject>()
{
new chartObject()
{
name = "chartObject5",
children = new List<chartObject>() { }
}
}
}
}
}
}
};
And got this as the result:
For calculations to be most efficient, cache their result in the node itself. Otherwise, you'll be re-calculating the count every time the descendants property is looked up.
The cost of doing that is the need to invalidate the cache all the way up the parent chain, like this:
public class chartObject
{
private chartObject _parent;
private int? _descCache = null;
public string name { get; set; }
public int descendants {
get {
return _descCache ?? calcDescendents();
}
}
public List<chartObject> children { get; set; }
public void AddChild(chartObject child) {
child._parent = this;
children.Add(child);
chartObject tmp = this;
while (tmp != null) {
tmp._descCache = null;
tmp = tmp._parent;
}
}
private int calcDescendents() {
return children.Count+children.Sum(child => child.descendants);
}
}
Walk all nodes of the tree (depth first is ok) and when done with children set "descendants property to sum of children's descendants + child count. You have to do it on every change to the tree structure. You should be able to limit updates only to parents of element that is changed.
If nodes made immutable you can populate the field at creation time.
Side notes:
Your tree is mutable as it is now (one can easily add more child nodes anywhere), so it may be safer to have method that counts descendants instead of property on a node.
Having computed property int descendants { get; set; } to be read/write is confusing as anyone can set its value to whatever number. Consider if making it read only and updating when one of child nodes changes (requires some custom notification mechanism).
Code style - consider naming classes with upper case names for code that is intended to be public (follow Microsoft's C# coding guidelines). chartObject -> ChartObject

Problem with circular reference list

I have a small problem and I would like to get your opinion.
I'm dealing with documents than can reference other documents. Starting from any document, I need to get the id of all the documents this document references. The problem is that the circular references are allowed so if A ref B ref C, again C can ref A and I get in the loop.
How can I solve this problem in C#?
An small example:
Let suppose that this is a class that represents a document:
public class Document
{
public Document(int id)
{
this.ID = id;
}
private int m_ID;
public int ID
{
get { return m_ID; }
set { m_ID = value; }
}
private List<Document> m_Children = new List<Document>();
public List<Document> Children
{
get { return m_Children; }
set { m_Children = value; }
}
private List<Document> m_Parent = new List<Document>();
public List<Document> Parent
{
get { return m_Parent; }
set { m_Parent = value; }
}
public Document AddChild(Document child)
{
child.Parent.Add(this);
this.Children.Add(child);
return child;
}
public Document AddChild(int child)
{
Document d = new Document(child);
return AddChild(d);
}
}
Now let's create a Document class that has some references:
public static Document CreateReferences()
{
Document d = new Document(1);
Document temp = d.AddChild(2);
for (int i = 3; i < 6; i++)
{
temp = temp.AddChild(i);
}
temp.AddChild(d);
return d;
}
Now I need to implement a method in Document class like
public List<int> GetReferencedDocuments()
{ }
What is the best way to do that? Any specific algorithm can be implemented?
Any suggestion is well accepted!
Thanks
Any tree-traversal algorithm would be fine.
As well as a list of docs you're going to build up, maintain a queue of documents you've yet to check, add the first document to that list.
Then, while the queue isn't empty, get the next doc, if it's not already in your list, then add it, and add all referenced docs to your queue.
List<Document> FoundDocs = new List<Documents();
Queue<Document> DocsToSearch = new Queue<Document>();
DocsToSearch.Enqueue(StartDoc);
while(DocsToSearch.Count != 0)
{
Document Doc = DocsToSearch.Dequeue();
if(!FoundDocs.Contains(Doc))
{
FoundDocs.Add(Doc);
foreach(var ChildDoc in Doc.Children)
{
DocsToSearch.Enqueue(ChildDoc);
}
}
}
The best way is to do a depth first search or a breadth first search
There are two main approaches to resolving this sort of recursive search on recursive data: marking or recording.
Marking: every time you list a document, flag it as viewed. Do not process flagged documents.
So your GetReferenceDocuments would look a little like this:
GetReferencedDocuments(startpoint)
if(startpoint.flagged) return null
startpoint.flag
new list result =startpoint
foreach(subdocument in
documents.children)
result.append(getreferenceddocuments(subdocuments))//
if not null
Recording: a similar approach, but the flag indicators are replaced by a list of already referenced documents ( a separate list of ids maybe ), and the flag check is a search on this list for this document.
Either way will work, depending on your objects, size and scale. If you cannot change the document objects, you will have to list them. If you have, potentially, 1M documents in your scan, you do not want to list them.
Example implementation:
public List<int> GetReferencedDocuments()
{
var referencedIds = new List<int>();
var queue = new Queue<Document>(this);
while (queue.Count > 0)
{
var newDocuments = queue.Dequeue().Children
.Where(d => !referencedIds.Contains(d.ID))
foreach (Document newDocument in newDocuments)
{
queue.Enqueue(newDocument);
referencedIds.Add(newDocument.ID);
}
}
return referencedIds;
}

Categories

Resources