Algorithm to group connected graphs I am working on an algorithm, which should group connected Arcs. The situation is described via code examples below.

I have Arcs:

public class Arc
{
    public Point StartPoint { get; set; }
    public Point EndPoint { get; set; }
    public bool Visited { get; set; }
    public Arc Successor { get; set; }
    public Arc Predecessor { get; set; }
}


that consist of Points:

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public override bool Equals(Object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        return obj.GetType() == GetType() &amp;&amp; Equals((Point)obj);
    }

    protected bool Equals(Point other)
    {
        return X.Equals(other.X) &amp;&amp; Y.Equals(other.Y);
    }

    public override int GetHashCode()
    {
        unchecked
        {
        return (X.GetHashCode() * 397) ^ Y.GetHashCode();
        }
    }
}


Given these Points and resulting Arcs:

var p1 = new Point {X = 0, Y = 0};
var p2 = new Point { X = 0, Y = 1 };
var p3 = new Point { X = 0, Y = 2 };
var p4 = new Point { X = 1, Y = 0 };
var p5 = new Point { X = 1, Y = 1 };

var arc1 = new Arc { StartPoint = p1, EndPoint = p2};
var arc2 = new Arc { StartPoint = p4, EndPoint = p5};
var arc3 = new Arc { StartPoint = p2, EndPoint = p3};


I would like to end up with groups of connected Arcs as a list of list:

var arcListOfList = new List&lt;List&lt;Arc&gt;&gt;();


This is the crude algorithm I came up with so far:

foreach (var arc in arcList)
{
    var successor = arcList.FirstOrDefault(x =&gt; x.StartPoint.Equals(arc.EndPoint));
    var predecessor = arcList.FirstOrDefault(x =&gt; x.EndPoint.Equals(arc.StartPoint));
    arc.Successor = successor;
    arc.Predecessor = predecessor;
}

Arc next;
do
{
    next = arcList.FirstOrDefault(x =&gt; x.Visited == false);
    var temp = new List&lt;Arc&gt;();

    if (next == null) continue;
    do
    {
        next.Visited = true;
        temp.Add(next);
        if (next.Successor != null)
        {
        next = next.Successor;
        }
        else
        {
        break;
        }
    } while (true);

    arcListOfList.Add(temp);
} while (next != null);


I would appreciate any help/suggestions to improve it.
I'm going to leave off suggesting anything about the algorithm for now as I don't fully understand what you want from it. Instead, I'm going to talk about your Point class in laborious depth... 

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }


I would argue that a point should be immutable - i.e. it doesn't change after you've created it. I would implement with full readonly properties:

private readonly int x;
public int X { get { return x; } }

private readonly int y;
public int Y { get { return y; } }

public Point(int x, int y)
{
   this.x = x;
   this.y = y
}


However, most people would let you off with private set auto properties:

public int X { get; private set; }


Let's look at your Equals implementations

public override bool Equals(Object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    return obj.GetType() == GetType() &amp;&amp; Equals((Point)obj);
}

protected bool Equals(Point other)
{
    return X.Equals(other.X) &amp;&amp; Y.Equals(other.Y);
}


Firstly, bool Equals(Point other) -> that's IEquatable&lt;Point&gt; if made public so your class should implement that:

public class Point : IEquatable&lt;Point&gt;


Now, simplify the object.Equals override: 

public override bool Equals(Object obj)
{
    return Equals(obj as Point);
}


And sharpen up the IEquatable&lt;Point&gt;.Equals:

public bool Equals(Point other)
{
    return other != null
            &amp;&amp; other.X == X
            &amp;&amp; other.Y == Y;
}


We should also override the == and != operators so that we're sure we are consistent with out equality:

public static bool operator ==(Point left, Point right)
{
    if (object.ReferenceEquals(left, null))
    {
        return object.ReferenceEquals(right, null);
    }

    return left.Equals(right);
}

public static bool operator !=(Point left, Point right)
{
    if (object.ReferenceEquals(left, null))
    {
        return !object.ReferenceEquals(right, null);
    }

    return !left.Equals(right);
}


Then you have a nice immutable class for your Point with consistent equality behaviour... Phew!

Edit

As EBrown pointed out in the comments, Point is a perfect fit for being a struct. It's less than 16 bytes, immutable and (0, 0) is a perfectly valid value (i.e. unitialized).