I am learning Algorithms, Part I on coursera.org. I just watched the first lecture then tried to write some code in C#. The class basically stores list of connected numbers. You can add numbers that connected together by calling Union
and check if they are connected by calling AreConnected
. Code is like below.
public class UnionFind
{
private readonly List<HashSet<int>> source;
public static UnionFind Create()
{
return new UnionFind();
}
private UnionFind()
{
this.source = new List<HashSet<int>>();
}
public void Union(int left, int right)
{
var isLeftExist = this.source.FirstOrDefault(o => o.Contains(left));
var isRightExist = this.source.FirstOrDefault(o => o.Contains(right));
if (isLeftExist == null &&
isRightExist == null)
{
var hash = new HashSet<int>();
hash.Add(left);
hash.Add(right);
this.source.Add(hash);
}
else if (isLeftExist != null &&
isRightExist == null)
{
isLeftExist.Add(right);
}
else if (isRightExist != null &&
isLeftExist == null)
{
isRightExist.Add(left);
}
else
{
// found left and right
this.source.Remove(isRightExist);
foreach (var item in isRightExist)
{
isLeftExist.Add(item);
}
}
}
public bool AreConnected(int left, int right)
{
return this.source
.Any(o =>
o.Contains(left) &&
o.Contains(right));
}
To make it easier to understand, this is unit test class.
[TestClass]
public class UnionFindTests
{
[TestMethod]
public void SimpleUnionTest()
{
int left = 10;
int right = 20;
var uf = UnionFind.Create();
uf.Union(left, right);
Assert.IsTrue(uf.AreConnected(left, right));
}
[TestMethod]
public void DuplicateUnionTest()
{
int left = 10;
int right = 10;
var uf = UnionFind.Create();
uf.Union(left, right);
Assert.IsTrue(uf.AreConnected(left, right));
}
[TestMethod]
public void MultipleLinksUnionTest()
{
int left1 = 10;
int left2 = 20;
int left3 = 30;
int right1 = 15;
int right2 = 25;
int right3 = 35;
var uf = UnionFind.Create();
uf.Union(left1, right1);
uf.Union(left2, right2);
uf.Union(left3, right3);
uf.Union(left1, right2);
Assert.IsTrue(uf.AreConnected(left2, right1));
}
}
UnionFind
works find and pass all tests in unit test. The problem is I found method Union has many if-else and I want to get rid of it. Is there a simpler way of implementing Union method?