Skip to content

Commit

Permalink
Merge pull request #38 from willwolfram18/feature/bst-implementation
Browse files Browse the repository at this point in the history
Feature/bst implementation - Closes #3
  • Loading branch information
realwoopee authored Oct 7, 2018
2 parents 561b332 + 0552d6b commit 69ea5f0
Show file tree
Hide file tree
Showing 9 changed files with 734 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"group": "build",
"presentation": {
"reveal": "silent"
},
"args": [
"build",
"'${workspaceFolder}/Algorithms'"
],
"problemMatcher": "$msCompile"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Algorithms.BinarySearchTree;
using FluentAssertions;
using System.Linq;
using Xunit;

namespace Algorithms.Tests.BinarySearchTreeTests
{
public class When_Data_Constructor_Is_Called
{
private const int DefaultData = 10;

private readonly BinarySearchTree<int> _tree;

public When_Data_Constructor_Is_Called()
{
_tree = new BinarySearchTree<int>(DefaultData);
}

[Fact]
public void Then_IsEmpty_Is_False()
{
_tree.IsEmpty.Should().BeFalse();
}

[Fact]
public void Then_Enumeration_Yields_Exactly_One_Item()
{
_tree.Count().Should().Be(1);
}

[Fact]
public void Then_Contains_Returns_True_For_Data_Used_At_Construction()
{
_tree.Contains(DefaultData).Should().BeTrue();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Algorithms.BinarySearchTree;
using FluentAssertions;
using Xunit;

namespace Algorithms.Tests.BinarySearchTreeTests
{
public class When_Default_Constructor_Is_Called
{
[Fact]
public void Then_IsEmpty_Is_True()
{
new BinarySearchTree<int>().IsEmpty.Should().BeTrue();
}

[Fact]
public void Then_Enumeration_Yields_No_Items()
{
new BinarySearchTree<int>().Should().BeEmpty();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Algorithms.BinarySearchTree;
using FluentAssertions;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace Algorithms.Tests
{
public class When_GetEnumerator_Is_Called
{
private readonly BinarySearchTree<int> _tree;

public When_GetEnumerator_Is_Called()
{
_tree = new BinarySearchTree<int>();
}

[Fact]
public void Then_Enumerator_Is_In_Order_Traversal()
{
_tree.Insert(4);
_tree.Insert(3);
_tree.Insert(1);
_tree.Insert(2);
_tree.Insert(6);
_tree.Insert(5);

var iterator = _tree.GetEnumerator();
iterator.MoveNext();

IteratorShouldBe(iterator, 1);
IteratorShouldBe(iterator, 2);
IteratorShouldBe(iterator, 3);
IteratorShouldBe(iterator, 4);
IteratorShouldBe(iterator, 5);
IteratorShouldBe(iterator, 6);
}

private static void IteratorShouldBe(IEnumerator<int> iterator, int value)
{
iterator.Current.Should().Be(value);
iterator.MoveNext();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using Algorithms.BinarySearchTree;
using FluentAssertions;
using System;
using Xunit;

namespace Algorithms.Tests.BinarySearchTreeTests
{
public class When_Insert_Is_Called
{
private readonly BinarySearchTree<int> _tree;

public When_Insert_Is_Called()
{
_tree = new BinarySearchTree<int>();
}

[Fact]
public void Then_Contains_Returns_True()
{
_tree.Insert(1);

_tree.Contains(1).Should().BeTrue();
}

[Theory]
[InlineData(2, 3, 6, 5, 4, 1)]
public void Then_Contains_Returns_True_For_All_Items(params int[] items)
{
foreach (var i in items)
{
_tree.Insert(i);
}

foreach (var i in items)
{
_tree.Contains(i).Should().BeTrue();
}
}

[Fact]
public void Then_Tree_Is_Not_Empty()
{
_tree.IsEmpty.Should().BeTrue();

_tree.Insert(10);

_tree.IsEmpty.Should().BeFalse();
}

[Fact]
public void If_Element_To_Insert_Is_A_Duplicate_Then_ArgumentException_Is_Thrown()
{
const int duplicateToInsert = 12;

_tree.Insert(duplicateToInsert);

Action badInsert = () => _tree.Insert(duplicateToInsert);

badInsert.Should().Throw<ArgumentException>("The element already exists in the tree.");
}

[Fact]
public void If_Element_Is_Less_Than_Root_Then_Element_Is_Inserted_Into_Left_Subtree()
{
const int rootNodeValue = 10;
const int valueToInsert = rootNodeValue - 1;

var rootNode = new Node<int>
{
Data = rootNodeValue
};
var tree = new BinarySearchTree<int>(rootNode);

tree.Insert(valueToInsert);

rootNode.LeftChild.Should().NotBeNull();
rootNode.LeftChild.Data.Should().Be(valueToInsert);
}

[Fact]
public void If_Element_Is_Greater_Than_Root_Then_Element_Is_Inserted_Into_Right_Subtree()
{
const int rootNodeValue = 10;
const int valueToInsert = rootNodeValue + 1;

var rootNode = new Node<int>
{
Data = rootNodeValue
};
var tree = new BinarySearchTree<int>(rootNode);

tree.Insert(valueToInsert);

rootNode.RightChild.Should().NotBeNull();
rootNode.RightChild.Data.Should().Be(valueToInsert);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using Algorithms.BinarySearchTree;
using FluentAssertions;
using System;
using System.Linq;
using Xunit;

namespace Algorithms.Tests.BinarySearchTreeTests
{
public class When_Node_Constructor_Is_Called
{
private const int DefaultData = 3;
private const int LeftChildData = DefaultData - 3;
private const int RightChildData = DefaultData + 3;

private readonly BinarySearchTree<int> _tree;

public When_Node_Constructor_Is_Called()
{
_tree = new BinarySearchTree<int>(new Node<int>
{
Data = DefaultData
});
}

[Fact]
public void If_Node_Is_Null_Then_ArgumentNullException_Is_Thrown()
{
Action badConstructor = () => new BinarySearchTree<int>(null);

badConstructor.Should().Throw<ArgumentNullException>();
}

[Fact]
public void Then_IsEmpty_Is_False()
{
_tree.IsEmpty.Should().BeFalse();
}

[Fact]
public void Then_Contains_Returns_True()
{
_tree.Contains(DefaultData).Should().BeTrue();
}

[Fact]
public void Then_Enumeration_Yields_Exactly_One_Item()
{
_tree.Count().Should().Be(1);
}

[Theory]
[InlineData(DefaultData, RightChildData)] // Left child is equal
[InlineData(LeftChildData, DefaultData)] // Right child is equal
[InlineData(DefaultData, DefaultData)] // Both children are equal
[InlineData(RightChildData, RightChildData)] // Left child is greater
[InlineData(LeftChildData, LeftChildData)] // Right child is lesser
[InlineData(RightChildData, LeftChildData)] // Left child is greater, right child is lesser
public void If_Root_Node_Is_Unsorted_Then_InvalidOperationException_Is_Thrown(int leftChild, int rightChild)
{
var unsortedNode = new Node<int>
{
Data = DefaultData,
LeftChild = new Node<int>
{
Data = leftChild
},
RightChild = new Node<int>
{
Data = rightChild
}
};

Action badConstruction = () => new BinarySearchTree<int>(unsortedNode);

badConstruction.Should().Throw<InvalidOperationException>("Root node is unsorted.");
}

[Theory]
[InlineData(LeftChildData, LeftChildData + 1)] // Left child is equal
[InlineData(LeftChildData - 1, LeftChildData)] // Right child is equal
[InlineData(LeftChildData, LeftChildData)] // Both children are equal
[InlineData(LeftChildData + 1, LeftChildData + 1)] // Left child is greater
[InlineData(LeftChildData - 1, LeftChildData - 1)] // Right child is lesser
[InlineData(LeftChildData + 1, LeftChildData - 1)] // Left child is greater, right child is lesser
public void If_Left_Subtree_Is_Unsorted_Then_InvalidOperationException_Is_Thrown(int leftChildOfLeftChild, int rightChildOfLeftChild)
{
var unsortedNode = new Node<int>
{
Data = DefaultData,
LeftChild = new Node<int>
{
Data = LeftChildData,
LeftChild = new Node<int>
{
Data = leftChildOfLeftChild
},
RightChild = new Node<int>
{
Data = rightChildOfLeftChild
}
}
};

Action badConstruction = () => new BinarySearchTree<int>(unsortedNode);

badConstruction.Should().Throw<InvalidOperationException>("Root node is unsorted.");
}

[Theory]
[InlineData(RightChildData, RightChildData + 1)] // Left child is equal
[InlineData(RightChildData - 1, RightChildData)] // Right child is equal
[InlineData(RightChildData, RightChildData)] // Both children are equal
[InlineData(RightChildData + 1, RightChildData + 1)] // Left child is greater
[InlineData(RightChildData - 1, RightChildData - 1)] // Right child is lesser
[InlineData(RightChildData + 1, RightChildData - 1)] // Left child is greater, right child is lesser
public void If_Right_Subtree_Is_Unsorted_Then_InvalidOperationException_Is_Thrown(int leftChildOfRightChild, int rightChildOfRightChild)
{
var unsortedNode = new Node<int>
{
Data = DefaultData,
RightChild = new Node<int>
{
Data = RightChildData,
LeftChild = new Node<int>
{
Data = leftChildOfRightChild
},
RightChild = new Node<int>
{
Data = rightChildOfRightChild
}
}
};

Action badConstruction = () => new BinarySearchTree<int>(unsortedNode);

badConstruction.Should().Throw<InvalidOperationException>("Root node is unsorted.");
}
}
}
Loading

0 comments on commit 69ea5f0

Please sign in to comment.