Browse Source

Merge branch 'remove-ngenerics'

pull/190/head
Steven Kirk 11 years ago
parent
commit
919a8c4192
  1. 9
      Perspex.sln
  2. 1
      nuget/build-version.ps1
  3. 4
      samples/XamlTestApplication/XamlTestApplication.csproj
  4. 19
      src/NGenerics/Constants.cs
  5. 80
      src/NGenerics/DataStructures/Comparers/ComparisonComparer.cs
  6. 93
      src/NGenerics/DataStructures/Comparers/KeyValuePairComparer.cs
  7. 84
      src/NGenerics/DataStructures/Comparers/ReverseComparer.cs
  8. 405
      src/NGenerics/DataStructures/General/Heap.cs
  9. 32
      src/NGenerics/DataStructures/General/HeapType.cs
  10. 44
      src/NGenerics/DataStructures/General/IHeap.cs
  11. 46
      src/NGenerics/DataStructures/Queues/IQueue.cs
  12. 556
      src/NGenerics/DataStructures/Queues/PriorityQueue.cs
  13. 30
      src/NGenerics/DataStructures/Queues/PriorityQueueType.cs
  14. 529
      src/NGenerics/DataStructures/Trees/BinarySearchTreeBase.cs
  15. 674
      src/NGenerics/DataStructures/Trees/BinaryTree.cs
  16. 68
      src/NGenerics/DataStructures/Trees/ISearchTree.cs
  17. 82
      src/NGenerics/DataStructures/Trees/ITree.cs
  18. 21
      src/NGenerics/DataStructures/Trees/NodeColor.cs
  19. 291
      src/NGenerics/DataStructures/Trees/RedBlackTree.cs
  20. 251
      src/NGenerics/DataStructures/Trees/RedBlackTreeDictionary.cs
  21. 232
      src/NGenerics/DataStructures/Trees/RedBlackTreeList.cs
  22. 107
      src/NGenerics/DataStructures/Trees/RedBlackTreeNode.cs
  23. 76
      src/NGenerics/NGenerics.csproj
  24. 34
      src/NGenerics/Patterns/Visitor/IVisitor.cs
  25. 51
      src/NGenerics/Patterns/Visitor/InOrderVisitor.cs
  26. 65
      src/NGenerics/Patterns/Visitor/KeyTrackingVisitor.cs
  27. 102
      src/NGenerics/Patterns/Visitor/OrderedVisitor.cs
  28. 65
      src/NGenerics/Patterns/Visitor/TrackingVisitor.cs
  29. 66
      src/NGenerics/Patterns/Visitor/ValueTrackingVisitor.cs
  30. 33
      src/NGenerics/Properties/AssemblyInfo.cs
  31. 59
      src/NGenerics/Util/Guard.cs
  32. 6
      src/Perspex.Base/Perspex.Base.csproj
  33. 8
      src/Perspex.Base/Threading/MainLoop.cs
  34. 16
      src/Perspex.Layout/LayoutManager.cs
  35. 4
      src/Perspex.Layout/Perspex.Layout.csproj
  36. 4
      tests/Perspex.Interactivity.UnitTests/Perspex.Interactivity.UnitTests.csproj
  37. 4
      tests/Perspex.Layout.UnitTests/Perspex.Layout.UnitTests.csproj
  38. 4
      tests/Perspex.Markup.Xaml.UnitTests/Perspex.Markup.Xaml.UnitTests.csproj

9
Perspex.sln

@ -31,10 +31,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Application", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Diagnostics", "src\Perspex.Diagnostics\Perspex.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{2BAFBE53-7FA4-4BB9-976F-9AFCC4F9847D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NGenerics", "src\NGenerics\NGenerics.csproj", "{415E048E-4611-4815-9CF2-D774E29079AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Animation", "src\Perspex.Animation\Perspex.Animation.csproj", "{D211E587-D8BC-45B9-95A4-F297C8FA5200}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}"
@ -163,10 +159,6 @@ Global
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.Build.0 = Release|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{415E048E-4611-4815-9CF2-D774E29079AC}.Release|Any CPU.Build.0 = Release|Any CPU
{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D211E587-D8BC-45B9-95A4-F297C8FA5200}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -251,7 +243,6 @@ Global
{811A76CF-1CF6-440F-963B-BBE31BD72A82} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{EC42600F-049B-43FF-AED1-8314D61B2749} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
{415E048E-4611-4815-9CF2-D774E29079AC} = {2BAFBE53-7FA4-4BB9-976F-9AFCC4F9847D}
{47ECDF59-DEF8-4C53-87B1-2098A3429059} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{5CCB5571-7C30-4E7D-967D-0E2158EBD91F} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{76716382-3159-460E-BDA6-C5715CF606D7} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}

1
nuget/build-version.ps1

@ -32,7 +32,6 @@ Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.dll
Copy-Item ..\src\Markup\Perspex.Markup.Xaml\bin\Release\Perspex.Markup.Xaml.xml $lib
Copy-Item ..\src\Perspex.HtmlRenderer\bin\Release\Perspex.HtmlRenderer.dll $lib
Copy-Item ..\src\Perspex.ReactiveUI\bin\Release\Perspex.ReactiveUI.dll $lib
Copy-Item ..\src\NGenerics\bin\Release\NGenerics.dll $lib
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\Perspex.Direct2D1.dll $build
Copy-Item ..\src\Windows\Perspex.Direct2D1\bin\Release\SharpDX.dll $build

4
samples/XamlTestApplication/XamlTestApplication.csproj

@ -85,10 +85,6 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Perspex.Animation\Perspex.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Perspex.Animation</Name>

19
src/NGenerics/Constants.cs

@ -1,19 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics
{
internal static class Constants
{
public const string NotEnoughSpaceInTheTargetArray = "Not enough space in the target array.";
}
}

80
src/NGenerics/DataStructures/Comparers/ComparisonComparer.cs

@ -1,80 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using NGenerics.Util;
namespace NGenerics.Comparers
{
/// <summary>
/// A Comparer using a Comparison delegate for comparisons between items.
/// </summary>
/// <typeparam name="T">The type of the objects to compare.</typeparam>
//[Serializable]
public sealed class ComparisonComparer<T> : IComparer<T>
{
#region Globals
private Comparison<T> _comparison;
#endregion
#region Construction
/// <param name="comparison">The comparison.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparison"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public ComparisonComparer(Comparison<T> comparison)
{
Guard.ArgumentNotNull(comparison, "comparison");
_comparison = comparison;
}
#endregion
#region Public Members
/// <summary>
/// Gets or sets the comparison used in this comparer.
/// </summary>
/// <value>The comparison used in this comparer.</value>
/// <exception cref="ArgumentNullException"><paramref name="value"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public Comparison<T> Comparison
{
get
{
return _comparison;
}
set
{
Guard.ArgumentNotNull(value, "value");
_comparison = value;
}
}
#endregion
#region IComparer<T> Members
/// <inheritdoc />
public int Compare(T x, T y)
{
return _comparison(x, y);
}
#endregion
}
}

93
src/NGenerics/DataStructures/Comparers/KeyValuePairComparer.cs

@ -1,93 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
namespace NGenerics.Comparers
{
/// <summary>
/// A comparer for comparing keys for the KeyValuePair class.
/// </summary>
/// <typeparam name="TKey">The key type.</typeparam>
/// <typeparam name="TValue">The value type.</typeparam>
//[Serializable]
public class KeyValuePairComparer<TKey, TValue> : IComparer<KeyValuePair<TKey, TValue>>
{
#region Globals
private readonly IComparer<TKey> _comparer;
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="KeyValuePairComparer&lt;TKey, TValue&gt;"/> class.
/// </summary>
public KeyValuePairComparer()
{
_comparer = Comparer<TKey>.Default;
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyValuePairComparer&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <param name="comparer">The comparer.</param>
public KeyValuePairComparer(IComparer<TKey> comparer)
{
if (comparer == null)
{
throw new ArgumentNullException("comparer");
}
_comparer = comparer;
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyValuePairComparer&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <param name="comparison">The comparison.</param>
public KeyValuePairComparer(Comparison<TKey> comparison)
{
if (comparison == null)
{
throw new ArgumentNullException("comparison");
}
_comparer = new ComparisonComparer<TKey>(comparison);
}
#endregion
#region IComparer<KeyValuePairComparer<TKey,TValue>> Members
/// <inheritdoc />
public int Compare(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
{
return _comparer.Compare(x.Key, y.Key);
}
#endregion
#region IComparer<TKey> Members
/// <inheritdoc />
public int Compare(TKey x, TKey y)
{
return _comparer.Compare(x, y);
}
#endregion
}
}

84
src/NGenerics/DataStructures/Comparers/ReverseComparer.cs

@ -1,84 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using NGenerics.Util;
namespace NGenerics.Comparers
{
/// <summary>
/// A comparer that wraps the IComparable interface to reproduce the opposite comparison result.
/// </summary>
/// <typeparam name="T">The type of the objects to compare.</typeparam>
//[Serializable]
public sealed class ReverseComparer<T> : IComparer<T>
{
#region Globals
private IComparer<T> _comparerToUse;
#endregion
#region Construction
/// <inheritdoc />
public ReverseComparer()
{
_comparerToUse = Comparer<T>.Default;
}
/// <param name="comparer">The comparer to reverse.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public ReverseComparer(IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
_comparerToUse = comparer;
}
#endregion
#region IComparer<T> Members
/// <inheritdoc />
public int Compare(T x, T y)
{
return (_comparerToUse.Compare(y, x));
}
#endregion
#region Public Members
/// <summary>
/// Gets or sets the comparer used in this instance.
/// </summary>
/// <value>The comparer.</value>
/// <exception cref="ArgumentNullException"><paramref name="value"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public IComparer<T> Comparer
{
get
{
return _comparerToUse;
}
set
{
Guard.ArgumentNotNull(value, "value");
_comparerToUse = value;
}
}
#endregion
}
}

405
src/NGenerics/DataStructures/General/Heap.cs

@ -1,405 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using NGenerics.Comparers;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Util;
namespace NGenerics.DataStructures.General
{
/// <summary>
/// An implementation of a Heap data structure.
/// </summary>
/// <typeparam name="T">The type of item stored in the <see cref="Heap{T}"/>.</typeparam>
//[Serializable]
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
public class Heap<T> : ICollection<T>, IHeap<T>
{
#region Globals
private const string heapIsEmpty = "The heap is empty.";
private readonly List<T> _data;
private readonly IComparer<T> _comparerToUse;
private readonly HeapType _thisType;
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of Heap to create.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Constructor" lang="cs" title="The following example shows how to use the default constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Constructor" lang="vbnet" title="The following example shows how to use the default constructor."/>
/// </example>
public Heap(HeapType type) : this(type, Comparer<T>.Default) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of heap.</param>
/// <param name="capacity">The capacity.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>
/// .
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="ConstructorCapacity" lang="cs" title="The following example shows how to use the capacity constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="ConstructorCapacity" lang="vbnet" title="The following example shows how to use the capacity constructor."/>
/// </example>
public Heap(HeapType type, int capacity) : this(type, capacity, Comparer<T>.Default) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of heap.</param>
/// <param name="comparer">The comparer.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
public Heap(HeapType type, Comparison<T> comparer) : this(type, new ComparisonComparer<T>(comparer)) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of heap.</param>
/// <param name="capacity">The capacity of the heap to start with.</param>
/// <param name="comparer">The comparer.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>
public Heap(HeapType type, int capacity, Comparison<T> comparer) : this(type, capacity, new ComparisonComparer<T>(comparer)) { }
/// <summary>
/// Initializes a new instance of the <see cref="Heap&lt;T&gt;"/> class.
/// </summary>
/// <param name="type">The type of Heap to create.</param>
/// <param name="comparer">The comparer to use.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="ConstructorComparer" lang="cs" title="The following example shows how to use the comparer constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="ConstructorComparer" lang="vbnet" title="The following example shows how to use the comparer constructor."/>
/// </example>
public Heap(HeapType type, IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
if ((type != HeapType.Minimum) && (type != HeapType.Maximum))
{
throw new ArgumentOutOfRangeException("type");
}
_thisType = type;
_data = new List<T> { default(T) };
_comparerToUse = type == HeapType.Minimum ? comparer : new ReverseComparer<T>(comparer);
}
/// <param name="type">The type of heap.</param>
/// <param name="capacity">The initial capacity of the Heap.</param>
/// <param name="comparer">The comparer to use.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than 0.</exception>.
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="type"/> is not either <see cref="HeapType.Maximum"/> or <see cref="HeapType.Minimum"/> .</exception>
public Heap(HeapType type, int capacity, IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
if ((type != HeapType.Minimum) && (type != HeapType.Maximum))
{
throw new ArgumentOutOfRangeException("type");
}
_thisType = type;
_data = new List<T>(capacity) { default(T) };
_comparerToUse = type == HeapType.Minimum ? comparer : new ReverseComparer<T>(comparer);
}
#endregion
#region Public Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Root" lang="cs" title="The following example shows how to use the Root property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Root" lang="vbnet" title="The following example shows how to use the Root property."/>
/// </example>
public T Root
{
get
{
#region Validation
if (Count == 0)
{
throw new InvalidOperationException(heapIsEmpty);
}
#endregion
return _data[1];
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="RemoveRoot" lang="cs" title="The following example shows how to use the RemoveRoot method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="RemoveRoot" lang="vbnet" title="The following example shows how to use the RemoveRoot method."/>
/// </example>
public T RemoveRoot()
{
#region Validation
if (Count == 0)
{
throw new InvalidOperationException(heapIsEmpty);
}
#endregion
// The minimum item to return.
var minimum = _data[1];
RemoveRootItem(minimum);
return minimum;
}
/// <summary>
/// Removes the root item.
/// </summary>
/// <param name="item">The item.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="RemoveRoot"/> method.
/// </remarks>
protected virtual void RemoveRootItem(T item)
{
// The last item in the heap
var last = _data[Count];
_data.RemoveAt(Count);
// If there's still items left in this heap, re-heapify it.
if (Count > 0)
{
// Re-heapify the binary tree to conform to the heap property
var counter = 1;
while ((counter * 2) < (_data.Count))
{
var child = counter * 2;
if (((child + 1) < (_data.Count)) &&
(_comparerToUse.Compare(_data[child + 1], _data[child]) < 0))
{
child++;
}
if (_comparerToUse.Compare(last, _data[child]) <= 0)
{
break;
}
_data[counter] = _data[child];
counter = child;
}
_data[counter] = last;
}
}
/// <summary>
/// Gets the type of heap represented by this instance.
/// </summary>
/// <value>The type of heap.</value>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Type" lang="cs" title="The following example shows how to use the Type property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Type" lang="vbnet" title="The following example shows how to use the Type property."/>
/// </example>
[SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
public HeapType Type => _thisType;
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="IsEmpty" lang="cs" title="The following example shows how to use the IsEmpty property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="IsEmpty" lang="vbnet" title="The following example shows how to use the IsEmpty property."/>
/// </example>
public bool IsEmpty => Count == 0;
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public bool Contains(T item)
{
return _data.Contains(item);
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="CopyTo" lang="cs" title="The following example shows how to use the CopyTo method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="CopyTo" lang="vbnet" title="The following example shows how to use the CopyTo method."/>
/// </example>
public void CopyTo(T[] array, int arrayIndex)
{
#region Validation
Guard.ArgumentNotNull(array, "array");
if ((array.Length - arrayIndex) < Count)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
for (var i = 1; i < _data.Count; i++)
{
array[arrayIndex++] = _data[i];
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Count" lang="cs" title="The following example shows how to use the Count property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Count" lang="vbnet" title="The following example shows how to use the Count property."/>
/// </example>
public int Count => _data.Count - 1;
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Add" lang="cs" title="The following example shows how to use the Add method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Add" lang="vbnet" title="The following example shows how to use the Add method."/>
/// </example>
public void Add(T item)
{
AddItem(item);
}
/// <summary>
/// Adds the item.
/// </summary>
/// <param name="item">The item to add.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Add"/> method.
/// </remarks>
protected virtual void AddItem(T item)
{
// Add a dummy to the end of the list (it will be replaced)
_data.Add(default(T));
var counter = _data.Count - 1;
while ((counter > 1) && (_comparerToUse.Compare(_data[counter / 2], item) > 0))
{
_data[counter] = _data[counter / 2];
counter = counter / 2;
}
_data[counter] = item;
}
/// <inheritdoc />
/// <exception cref="NotSupportedException">Always.</exception>
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="GetEnumerator" lang="cs" title="The following example shows how to use the GetEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="GetEnumerator" lang="vbnet" title="The following example shows how to use the GetEnumerator method."/>
/// </example>
public IEnumerator<T> GetEnumerator()
{
for (var i = 1; i < _data.Count; i++)
{
yield return _data[i];
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="Clear" lang="cs" title="The following example shows how to use the Clear method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="Clear" lang="vbnet" title="The following example shows how to use the Clear method."/>
/// </example>
public void Clear()
{
ClearItems();
}
/// <summary>
/// Clears all the objects in this instance.
/// </summary>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void ClearItems()
{
_data.RemoveRange(1, _data.Count - 1); // Clears all objects in this instance except the first dummy one.
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\General\HeapExamples.cs" region="IsReadOnly" lang="cs" title="The following example shows how to use the IsReadOnly property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\General\HeapExamples.vb" region="IsReadOnly" lang="vbnet" title="The following example shows how to use the IsReadOnly property."/>
/// </example>
public bool IsReadOnly => false;
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}

32
src/NGenerics/DataStructures/General/HeapType.cs

@ -1,32 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.DataStructures.General
{
/// <summary>
/// The type of <see cref="Heap{T}"/> to implemented.
/// </summary>
public enum HeapType
{
/// <summary>
/// Makes the heap a Minimum-Heap - the smallest item is kept in the root of the <see cref="Heap{T}"/>.
/// </summary>
Minimum,
/// <summary>
/// Makes the heap a Maximum-Heap - the largest item is kept in the root of the <see cref="Heap{T}"/>.
/// </summary>
Maximum
}
}

44
src/NGenerics/DataStructures/General/IHeap.cs

@ -1,44 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
namespace NGenerics.DataStructures.General
{
/// <summary>
/// An interface for the <see cref="Heap{T}"/> data structure.
/// </summary>
/// <typeparam name="T">The type of elements in the heap.</typeparam>
public interface IHeap<T>
{
/// <summary>
/// Adds the specified item.
/// </summary>
/// <param name="item">The item.</param>
void Add(T item);
/// <summary>
/// Removes the root and returns it.
/// </summary>
/// <returns>The root of the <see cref="Heap{T}"/>.</returns>
/// <exception cref="InvalidOperationException">The <see cref="Graph{T}"/> is empty.</exception>
T RemoveRoot();
/// <summary>
/// Gets the root.
/// </summary>
/// <value>The root.</value>
/// <exception cref="InvalidOperationException">The <see cref="Heap{T}"/> is empty.</exception>
T Root { get; }
}
}

46
src/NGenerics/DataStructures/Queues/IQueue.cs

@ -1,46 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Queues
{
/// <summary>
/// A queue interface.
/// </summary>
/// <typeparam name="T">The type of the elements in the queue.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
public interface IQueue<T>
{
/// <summary>
/// Enqueues the item at the back of the queue.
/// </summary>
/// <param name="item">The item.</param>
void Enqueue(T item);
/// <summary>
/// Dequeues the item at the front of the queue.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <exception cref="InvalidOperationException">The <see cref="Deque{T}"/> is empty.</exception>
T Dequeue();
/// <summary>
/// Peeks at the item in the front of the queue, without removing it.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <exception cref="InvalidOperationException">The <see cref="Deque{T}"/> is empty.</exception>
T Peek();
}
}

556
src/NGenerics/DataStructures/Queues/PriorityQueue.cs

@ -1,556 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
Community contributions :
- TKey Peek(out TPriority) contributed by Karl Shulze (http://www.karlschulze.com/).</remarks>
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Comparers;
using NGenerics.DataStructures.Trees;
using NGenerics.Util;
namespace NGenerics.DataStructures.Queues
{
/// <summary>
/// An implementation of a Priority Queue (can be <see cref="PriorityQueueType.Minimum"/> or <see cref="PriorityQueueType.Maximum"/>).
/// </summary>
/// <typeparam name="TPriority">The type of the priority in the <see cref="PriorityQueue{TPriority, TValue}"/>.</typeparam>
/// <typeparam name="TValue">The type of the elements in the <see cref="PriorityQueue{TPriority, TValue}"/>.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
//[Serializable]
public class PriorityQueue<TValue, TPriority> : ICollection<TValue>, IQueue<TValue>
{
#region Globals
private readonly RedBlackTreeList<TPriority, TValue> _tree;
private TPriority _defaultPriority;
private readonly PriorityQueueType _queueType;
#endregion
#region Construction
/// <param name="queueType">Type of the queue.</param>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Constructor" lang="cs" title="The following example shows how to use the default constructor."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Constructor" lang="vbnet" title="The following example shows how to use the default constructor."/>
/// </example>
public PriorityQueue(PriorityQueueType queueType) :
this(queueType, Comparer<TPriority>.Default)
{
}
/// <inheritdoc/>
public PriorityQueue(PriorityQueueType queueType, IComparer<TPriority> comparer)
{
if ((queueType != PriorityQueueType.Minimum) && (queueType != PriorityQueueType.Maximum))
{
throw new ArgumentOutOfRangeException("queueType");
}
_queueType = queueType;
_tree = new RedBlackTreeList<TPriority, TValue>(comparer);
}
/// <summary>
/// Initializes a new instance of the <see cref="PriorityQueue&lt;TValue, TPriority&gt;"/> class.
/// </summary>
/// <param name="queueType">Type of the queue.</param>
/// <param name="comparison">The comparison.</param>
/// <inheritdoc/>
public PriorityQueue(PriorityQueueType queueType, Comparison<TPriority> comparison) :
this(queueType, new ComparisonComparer<TPriority>(comparison))
{
}
#endregion
#region IQueue<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Enqueue" lang="cs" title="The following example shows how to use the Enqueue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Enqueue" lang="vbnet" title="The following example shows how to use the Enqueue method."/>
/// </example>
public void Enqueue(TValue item)
{
Add(item);
}
/// <summary>
/// Enqueues the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="priority">The priority.</param>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="EnqueuePriority" lang="cs" title="The following example shows how to use the Enqueue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="EnqueuePriority" lang="vbnet" title="The following example shows how to use the Enqueue method."/>
/// </example>
public void Enqueue(TValue item, TPriority priority)
{
Add(item, priority);
}
/// <summary>
/// Dequeues the item at the front of the queue.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Dequeue" lang="cs" title="The following example shows how to use the Dequeue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Dequeue" lang="vbnet" title="The following example shows how to use the Dequeue method."/>
/// </example>
public TValue Dequeue()
{
TPriority priority;
return Dequeue(out priority);
}
/// <summary>
/// Peeks at the item in the front of the queue, without removing it.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Peek" lang="cs" title="The following example shows how to use the Peek method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Peek" lang="vbnet" title="The following example shows how to use the Peek method."/>
/// </example>
public TValue Peek()
{
var association = GetNextItem();
// Always dequeue in FIFO manner
return association.Value.First.Value;
}
/// <summary>
/// Peeks at the item in the front of the queue, without removing it.
/// </summary>
/// <param name="priority">The priority of the item.</param>
/// <returns>The item at the front of the queue.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="PeekPriority" lang="cs" title="The following example shows how to use the Peek method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="PeekPriority" lang="vbnet" title="The following example shows how to use the Peek method."/>
/// </example>
public TValue Peek(out TPriority priority)
{
var association = GetNextItem();
var item = association.Value.First.Value;
priority = association.Key;
return item;
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="IsReadOnly" lang="cs" title="The following example shows how to use the IsReadOnly property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="IsReadOnly" lang="vbnet" title="The following example shows how to use the IsReadOnly property."/>
/// </example>
public bool IsReadOnly => false;
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="GetEnumerator" lang="cs" title="The following example shows how to use the GetEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="GetEnumerator" lang="vbnet" title="The following example shows how to use the GetEnumerator method."/>
/// </example>
public IEnumerator<TValue> GetEnumerator()
{
return _tree.GetValueEnumerator();
}
#endregion
#region Public Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Count" lang="cs" title="The following example shows how to use the Count property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Count" lang="vbnet" title="The following example shows how to use the Count property."/>
/// </example>
public int Count { get; private set; }
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public bool Contains(TValue item)
{
return _tree.ContainsValue(item);
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="CopyTo" lang="cs" title="The following example shows how to use the CopyTo method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="CopyTo" lang="vbnet" title="The following example shows how to use the CopyTo method."/>
/// </example>
public void CopyTo(TValue[] array, int arrayIndex)
{
#region Validation
Guard.ArgumentNotNull(array, "array");
if ((array.Length - arrayIndex) < Count)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
foreach (var association in _tree)
{
var items = association.Value;
foreach (var item in items)
{
array.SetValue(item, arrayIndex++);
}
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Add" lang="cs" title="The following example shows how to use the Add method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Add" lang="vbnet" title="The following example shows how to use the Add method."/>
/// </example>
public void Add(TValue item)
{
Add(item, _defaultPriority);
}
/// <summary>
/// Adds an item to the <see cref="ICollection{T}"/>.
/// </summary>
/// <param name="item">The object to add to the <see cref="ICollection{T}"/>.</param>
/// <param name="priority">The priority of the item.</param>
/// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only.</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="AddPriority" lang="cs" title="The following example shows how to use the Add method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="AddPriority" lang="vbnet" title="The following example shows how to use the Add method."/>
/// </example>
public void Add(TValue item, TPriority priority)
{
AddItem(item, priority);
}
/// <inheritdoc />
public bool Remove(TValue item)
{
TPriority priority;
return Remove(item, out priority);
}
/// <summary>
/// Returns an enumerator that iterates through the keys in the collection.
/// </summary>
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the keys in the collection.</returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="GetKeyEnumerator" lang="cs" title="The following example shows how to use the GetKeyEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="GetKeyEnumerator" lang="vbnet" title="The following example shows how to use the GetKeyEnumerator method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IEnumerator<KeyValuePair<TPriority, TValue>> GetKeyEnumerator()
{
return _tree.GetKeyEnumerator();
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="Clear" lang="cs" title="The following example shows how to use the Clear method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="Clear" lang="vbnet" title="The following example shows how to use the Clear method."/>
/// </example>
public void Clear()
{
ClearItems();
}
/// <summary>
/// Dequeues the item from the head of the queue.
/// </summary>
/// <param name="priority">The priority of the item to dequeue.</param>
/// <returns>The item at the head of the queue.</returns>
/// <exception cref="InvalidOperationException">The <see cref="PriorityQueue{TValue, TPriority}"/> is empty.</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Queues\PriorityQueueExamples.cs" region="DequeueWithPriority" lang="cs" title="The following example shows how to use the Dequeue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Queues\PriorityQueueExamples.vb" region="DequeueWithPriority" lang="vbnet" title="The following example shows how to use the Dequeue method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
public TValue Dequeue(out TPriority priority)
{
return DequeueItem(out priority);
}
/// <summary>
/// Dequeues the item at the front of the queue.
/// </summary>
/// <returns>The item at the front of the queue.</returns>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Dequeue()"/> or <see cref="Dequeue(out TPriority)"/> methods.
/// </remarks>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#")]
protected virtual TValue DequeueItem(out TPriority priority)
{
var association = GetNextItem();
var item = association.Value.First.Value;
association.Value.RemoveFirst();
var key = association.Key;
if (association.Value.Count == 0)
{
_tree.Remove(association.Key);
}
Count--;
priority = key;
return item;
}
/// <summary>
/// Gets or sets the default priority.
/// </summary>
/// <value>The default priority.</value>
public TPriority DefaultPriority
{
get
{
return _defaultPriority;
}
set
{
_defaultPriority = value;
}
}
/// <summary>
/// Removes the first occurrence of the specified item from the property queue.
/// </summary>
/// <param name="item">The item to remove.</param>
/// <param name="priority">The priority associated with the item.</param>
/// <returns><c>true</c> if the item exists in the <see cref="PriorityQueue{TValue, TPriority}"/> and has been removed; otherwise <c>false</c>.</returns>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")]
public bool Remove(TValue item, out TPriority priority)
{
return RemoveItem(item, out priority);
}
/// <summary>
/// Removes the item.
/// </summary>
/// <param name="item">The item to remove</param>
/// <param name="priority">The priority of the item that was removed.</param>
/// <returns>An indication of whether the item was found, and removed.</returns>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Remove(TValue,out TPriority)"/> method.
/// </remarks>
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")]
protected virtual bool RemoveItem(TValue item, out TPriority priority)
{
var removed = _tree.Remove(item, out priority);
if (removed)
{
Count--;
}
return removed;
}
/// <summary>
/// Removes the items with the specified priority.
/// </summary>
/// <param name="priority">The priority.</param>
/// <returns><c>true</c> if the priority exists in the <see cref="PriorityQueue{TValue, TPriority}"/> and has been removed; otherwise <c>false</c>.</returns>
public bool RemovePriorityGroup(TPriority priority)
{
return RemoveItems(priority);
}
/// <summary>
/// Removes the items from the collection with the specified priority.
/// </summary>
/// <param name="priority">The priority to search for.</param>
/// <returns>An indication of whether items were found having the specified priority.</returns>
protected virtual bool RemoveItems(TPriority priority)
{
LinkedList<TValue> items;
if (_tree.TryGetValue(priority, out items))
{
_tree.Remove(priority);
Count -= items.Count;
return true;
}
return false;
}
/// <summary>
/// Removes the items with the specified priority.
/// </summary>
/// <param name="priority">The priority.</param>
/// <returns>The items with the specified priority.</returns>
public IList<TValue> GetPriorityGroup(TPriority priority)
{
LinkedList<TValue> items;
return _tree.TryGetValue(priority, out items) ? new List<TValue>(items) : new List<TValue>();
}
/// <summary>
/// Adds the specified items to the priority queue with the specified priority.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="priority">The priority.</param>
/// <exception cref="ArgumentNullException"><paramref name="items"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public void AddPriorityGroup(IList<TValue> items, TPriority priority)
{
#region Validation
Guard.ArgumentNotNull(items, "items");
#endregion
AddPriorityGroupItem(items, priority);
}
/// <summary>
/// Adds the specified items to the priority queue with the specified priority.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="priority">The priority.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="AddPriorityGroup"/> method.
/// </remarks>
protected virtual void AddPriorityGroupItem(IList<TValue> items, TPriority priority)
{
LinkedList<TValue> currentValues;
if (_tree.TryGetValue(priority, out currentValues))
{
for (var i = 0; i < items.Count; i++)
{
currentValues.AddLast(items[i]);
}
}
else
{
currentValues = new LinkedList<TValue>(items);
_tree.Add(priority, currentValues);
}
}
#endregion
#region Protected Members
/// <summary>
/// Adds the item to the queue.
/// </summary>
/// <param name="item">The item to add.</param>
/// <param name="priority">The priority of the item.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Add(TValue,TPriority)"/> method.
/// </remarks>
protected virtual void AddItem(TValue item, TPriority priority)
{
LinkedList<TValue> list;
if (_tree.TryGetValue(priority, out list))
{
list.AddLast(item);
}
else
{
list = new LinkedList<TValue>();
list.AddLast(item);
_tree.Add(priority, list);
}
Count++;
}
/// <summary>
/// Clears all the objects in this instance.
/// </summary>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void ClearItems()
{
_tree.Clear();
Count = 0;
}
#endregion
#region Private Members
/// <summary>
/// Checks if the list is not empty, and if it is, throw an exception.
/// </summary>
private void CheckTreeNotEmpty()
{
if (_tree.Count == 0)
{
throw new InvalidOperationException("The Priority Queue is empty.");
}
}
/// <summary>
/// Gets the next item.
/// </summary>
private KeyValuePair<TPriority, LinkedList<TValue>> GetNextItem()
{
#region Validation
CheckTreeNotEmpty();
#endregion
return _queueType == PriorityQueueType.Maximum ? _tree.Maximum : _tree.Minimum;
}
#endregion
}
}

30
src/NGenerics/DataStructures/Queues/PriorityQueueType.cs

@ -1,30 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.DataStructures.Queues
{
/// <summary>
/// Specifies the Priority Queue type (min or max).
/// </summary>
public enum PriorityQueueType
{
/// <summary>
/// Specify a Minimum <see cref="PriorityQueue{TValue, TPriority}"/>.
/// </summary>
Minimum = 0,
/// <summary>
/// Specify a Maximum <see cref="PriorityQueue{TValue, TPriority}"/>.
/// </summary>
Maximum = 1
}
}

529
src/NGenerics/DataStructures/Trees/BinarySearchTreeBase.cs

@ -1,529 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Comparers;
using NGenerics.Patterns.Visitor;
using NGenerics.Util;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// A base class for Binary Search Trees that store a single value in each node.
/// </summary>
/// <typeparam name="T"></typeparam>
//[Serializable]
public abstract class BinarySearchTreeBase<T> : ISearchTree<T>
{
#region Globals
internal const string alreadyContainedInTheTree = "The item is already contained in the tree.";
private BinaryTree<T> _tree;
private readonly IComparer<T> _comparer;
#endregion
#region Delegates
/// <summary>
/// A custom comparison between some search value and the type of item that is kept in the tree.
/// </summary>
/// <typeparam name="TSearch">The type of the search.</typeparam>
protected delegate int CustomComparison<TSearch>(TSearch value, T item);
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="BinarySearchTreeBase{T}"/> class.
/// </summary>
protected BinarySearchTreeBase()
{
_comparer = Comparer<T>.Default;
}
/// <summary>
/// Initializes a new instance of the <see cref="BinarySearchTreeBase{T}"/> class.
/// </summary>
/// <param name="comparer">The comparer to use when comparing items.</param>
/// <exception cref="ArgumentNullException"><paramref name="comparer"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
protected BinarySearchTreeBase(IComparer<T> comparer)
{
Guard.ArgumentNotNull(comparer, "comparer");
_comparer = comparer;
}
/// <summary>
/// Initializes a new instance of the <see cref="BinarySearchTreeBase&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <param name="comparison">The comparison.</param>
protected BinarySearchTreeBase(Comparison<T> comparison)
{
Guard.ArgumentNotNull(comparison, "comparison");
_comparer = new ComparisonComparer<T>(comparison);
}
#endregion
#region Public Members
/// <summary>
/// Gets the comparer.
/// </summary>
/// <value>The comparer.</value>
public IComparer<T> Comparer => _comparer;
#endregion
#region Protected Members
/// <summary>
/// Finds the node containing the specified data key.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>
/// The node with the specified key if found. If the key is not in the tree, this method returns null.
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected virtual BinaryTree<T> FindNode(T item)
{
if (_tree == null)
{
return null;
}
var currentNode = _tree;
while (currentNode != null)
{
var nodeResult = _comparer.Compare(item, currentNode.Data);
if (nodeResult == 0)
{
return currentNode;
}
currentNode = nodeResult < 0 ? currentNode.Left : currentNode.Right;
}
return null;
}
/// <summary>
/// Finds the node that matches the custom delegate.
/// </summary>
/// <typeparam name="TSearch">The type of the search.</typeparam>
/// <param name="value">The value.</param>
/// <param name="customComparison">The custom comparison.</param>
/// <returns>The item if found, else null.</returns>
protected virtual BinaryTree<T> FindNode<TSearch>(TSearch value, CustomComparison<TSearch> customComparison)
{
if (_tree == null)
{
return null;
}
var currentNode = _tree;
while (currentNode != null)
{
var nodeResult = customComparison(value, currentNode.Data);
if (nodeResult == 0)
{
return currentNode;
}
currentNode = nodeResult < 0 ? currentNode.Left : currentNode.Right;
}
return null;
}
/// <summary>
/// Removes the item from the tree.
/// </summary>
/// <param name="item">The item to remove.</param>
/// <returns>An indication of whether the item has been removed from the tree.</returns>
protected abstract bool RemoveItem(T item);
/// <summary>
/// Adds the item.
/// </summary>
/// <param name="item">The item.</param>
protected abstract void AddItem(T item);
/// <summary>
/// Find the maximum node.
/// </summary>
/// <returns>The maximum node.</returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected BinaryTree<T> FindMaximumNode()
{
#region Debug
Debug.Assert(_tree != null);
#endregion
return FindMaximumNode(_tree);
}
/// <summary>
/// Find the minimum node.
/// </summary>
/// <returns>The minimum node.</returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected BinaryTree<T> FindMinimumNode()
{
#region Debug
Debug.Assert(_tree != null);
#endregion
return FindMinimumNode(_tree);
}
/// <summary>
/// Finds the maximum node.
/// </summary>
/// <param name="startNode">The start node.</param>
/// <returns>The maximum node below this node.</returns>
[SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
protected static BinaryTree<T> FindMaximumNode(BinaryTree<T> startNode)
{
#region Asserts
Debug.Assert(startNode != null);
#endregion
var searchNode = startNode;
while (searchNode.Right != null)
{
searchNode = searchNode.Right;
}
return searchNode;
}
/// <summary>
/// Finds the minimum node.
/// </summary>
/// <param name="startNode">The start node.</param>
/// <returns>The minimum node below this node.</returns>
[SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
protected static BinaryTree<T> FindMinimumNode(BinaryTree<T> startNode)
{
#region Asserts
Debug.Assert(startNode != null);
#endregion
var searchNode = startNode;
while (searchNode.Left != null)
{
searchNode = searchNode.Left;
}
return searchNode;
}
/// <summary>
/// Gets or sets the <see cref="BinaryTree{T}"/> for this <see cref="BinarySearchTreeBase{TKey,TValue}"/>.
/// </summary>
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
protected BinaryTree<T> Tree
{
get
{
return _tree;
}
set
{
_tree = value;
}
}
#endregion
#region Private Members
/// <summary>
/// Visits the node in an in-order fashion.
/// </summary>
/// <param name="node">The node.</param>
/// <param name="visitor">The visitor.</param>
private static void VisitNode(BinaryTree<T> node, OrderedVisitor<T> visitor)
{
if (node != null)
{
var pair = node.Data;
visitor.VisitPreOrder(pair);
VisitNode(node.Left, visitor);
visitor.VisitInOrder(pair);
VisitNode(node.Right, visitor);
visitor.VisitPostOrder(pair);
}
}
#endregion
#region ISearchTree<TKey,TValue> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Minimum" lang="cs" title="The following example shows how to use the Minimum property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Minimum" lang="vbnet" title="The following example shows how to use the Minimum property."/>
/// </example>
public virtual T Minimum
{
get
{
#region Validation
ValidateEmpty();
#endregion
return FindMinimumNode().Data;
}
}
private void ValidateEmpty()
{
if (Count == 0)
{
throw new InvalidOperationException("The search tree is empty.");
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Maximum" lang="cs" title="The following example shows how to use the Maximum property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Maximum" lang="vbnet" title="The following example shows how to use the Maximum property."/>
/// </example>
public virtual T Maximum
{
get
{
ValidateEmpty();
return FindMaximumNode().Data;
}
} /// <inheritdoc/>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
public void DepthFirstTraversal(OrderedVisitor<T> visitor)
{
Guard.ArgumentNotNull(visitor, "visitor");
VisitNode(_tree, visitor);
}
/// <inheritdoc/>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IEnumerator<T> GetOrderedEnumerator()
{
if (_tree != null)
{
var trackingVisitor = new TrackingVisitor<T>();
var inOrderVisitor = new InOrderVisitor<T>(trackingVisitor);
_tree.DepthFirstTraversal(inOrderVisitor);
var trackingList = trackingVisitor.TrackingList;
for (var i = 0; i < trackingList.Count; i++)
{
yield return trackingList[i];
}
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="IsEmpty" lang="cs" title="The following example shows how to use the IsEmpty property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="IsEmpty" lang="vbnet" title="The following example shows how to use the IsEmpty property."/>
/// </example>
public bool IsEmpty => Count == 0;
/// <inheritdoc />
public bool Remove(T item)
{
var itemRemoved = RemoveItem(item);
if (itemRemoved)
{
Count--;
}
return itemRemoved;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Clear" lang="cs" title="The following example shows how to use the Clear method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Clear" lang="vbnet" title="The following example shows how to use the Clear method."/>
/// </example>
public void Clear()
{
ClearItems();
}
/// <summary>
/// Clears all the objects in this instance.
/// </summary>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void ClearItems()
{
_tree = null;
Count = 0;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Count" lang="cs" title="The following example shows how to use the Count property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Count" lang="vbnet" title="The following example shows how to use the Count property."/>
/// </example>
public int Count { get; private set; }
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="GetEnumerator" lang="cs" title="The following example shows how to use the GetEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="GetEnumerator" lang="vbnet" title="The following example shows how to use the GetEnumerator method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
public IEnumerator<T> GetEnumerator()
{
if (_tree != null)
{
var stack = new Stack<BinaryTree<T>>();
stack.Push(_tree);
while (stack.Count > 0)
{
var binaryTree = stack.Pop();
yield return binaryTree.Data;
if (binaryTree.Left != null)
{
stack.Push(binaryTree.Left);
}
if (binaryTree.Right != null)
{
stack.Push(binaryTree.Right);
}
}
}
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="AddKeyValuePair" lang="cs" title="The following example shows how to use the AddKeyValuePair method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="AddKeyValuePair" lang="vbnet" title="The following example shows how to use the AddKeyValuePair method."/>
/// </example>
public void Add(T item)
{
AddItem(item);
Count++;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public virtual bool Contains(T item)
{
var node = FindNode(item);
return node != null;
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="CopyTo" lang="cs" title="The following example shows how to use the CopyTo method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="CopyTo" lang="vbnet" title="The following example shows how to use the CopyTo method."/>
/// </example>
public void CopyTo(T[] array, int arrayIndex)
{
#region Validation
Guard.ArgumentNotNull(array, "array");
if ((array.Length - arrayIndex) < Count)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
foreach (var association in _tree)
{
array[arrayIndex++] = association;
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="IsReadOnly" lang="cs" title="The following example shows how to use the IsReadOnly property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="IsReadOnly" lang="vbnet" title="The following example shows how to use the IsReadOnly property."/>
/// </example>
public bool IsReadOnly => false;
#endregion
}
}

674
src/NGenerics/DataStructures/Trees/BinaryTree.cs

@ -1,674 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using NGenerics.Patterns.Visitor;
using NGenerics.Util;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An implementation of a Binary Tree data structure.
/// </summary>
/// <typeparam name="T">The type of elements in the <see cref="BinaryTree{T}"/>.</typeparam>
//[Serializable]
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
public class BinaryTree<T> : ICollection<T>, ITree<T>
{
#region Globals
private BinaryTree<T> _leftSubtree;
private BinaryTree<T> _rightSubtree;
private T _data;
#endregion
#region Construction
/// <param name="data">The data contained in this node.</param>
public BinaryTree(T data) : this(data, null, null) { }
/// <param name="data">The data.</param>
/// <param name="left">The data of the left subtree.</param>
/// <param name="right">The data of the right subtree.</param>
public BinaryTree(T data, T left, T right) : this(data, new BinaryTree<T>(left), new BinaryTree<T>(right)) { }
/// <param name="data">The data contained in this node.</param>
/// <param name="left">The left subtree.</param>
/// <param name="right">The right subtree.</param>
public BinaryTree(T data, BinaryTree<T> left, BinaryTree<T> right)
: this(data, left, right, true)
{
}
/// <param name="data">The data contained in this node.</param>
/// <param name="left">The left subtree.</param>
/// <param name="right">The right subtree.</param>
/// <param name="validateData"><see langword="true"/> to validate <paramref name="data"/>; otherwise <see langword="false"/>.</param>
internal BinaryTree(T data, BinaryTree<T> left, BinaryTree<T> right, bool validateData)
{
#region Validation
//TODO: probably not the most efficient way of doing this but SplayTree needs to use a BinaryTree with null data.
if (validateData)
{
Guard.ArgumentNotNull(data, "data");
}
#endregion
_leftSubtree = left;
if (left != null)
{
left.Parent = this;
}
_rightSubtree = right;
if (right != null)
{
right.Parent = this;
}
_data = data;
}
#endregion
#region ICollection<T> Members
/// <inheritdoc />
public bool IsEmpty => Count == 0;
/// <inheritdoc />
public bool IsFull => (_leftSubtree != null) && (_rightSubtree != null);
/// <inheritdoc />
public bool Contains(T item)
{
foreach (var thisItem in this)
{
if (item.Equals(thisItem))
{
return true;
}
}
return false;
}
/// <inheritdoc />
public void CopyTo(T[] array, int arrayIndex)
{
Guard.ArgumentNotNull(array, "array");
foreach (var item in this)
{
#region Validation
if (arrayIndex >= array.Length)
{
throw new ArgumentException(Constants.NotEnoughSpaceInTheTargetArray, "array");
}
#endregion
array[arrayIndex++] = item;
}
}
/// <inheritdoc />
public int Count
{
get
{
var count = 0;
if (_leftSubtree != null)
{
count++;
}
if (_rightSubtree != null)
{
count++;
}
return count;
}
}
/// <inheritdoc />
public void Add(T item)
{
AddItem(new BinaryTree<T>(item));
}
/// <inheritdoc />
public bool Remove(T item)
{
if (_leftSubtree != null)
{
if (_leftSubtree._data.Equals(item))
{
RemoveLeft();
return true;
}
}
if (_rightSubtree != null)
{
if (_rightSubtree._data.Equals(item))
{
RemoveRight();
return true;
}
}
return false;
}
/// <summary>
/// Removes the specified child.
/// </summary>
/// <param name="child">The child.</param>
/// <returns>A value indicating whether the child was found (and removed) from this tree.</returns>
public bool Remove(BinaryTree<T> child)
{
if (_leftSubtree != null)
{
if (_leftSubtree == child)
{
RemoveLeft();
return true;
}
}
if (_rightSubtree != null)
{
if (_rightSubtree == child)
{
RemoveRight();
return true;
}
}
return false;
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
public IEnumerator<T> GetEnumerator()
{
var stack = new Stack<BinaryTree<T>>();
stack.Push(this);
while (stack.Count > 0)
{
var tree = stack.Pop();
yield return tree.Data;
if (tree._leftSubtree != null)
{
stack.Push(tree._leftSubtree);
}
if (tree._rightSubtree != null)
{
stack.Push(tree._rightSubtree);
}
}
}
/// <inheritdoc />
public virtual void Clear()
{
if (_leftSubtree != null)
{
_leftSubtree.Parent = null;
_leftSubtree = null;
}
if (_rightSubtree != null)
{
_rightSubtree.Parent = null;
_rightSubtree = null;
}
}
#endregion
#region ITree<T> Members
/// <inheritdoc />
void ITree<T>.Add(ITree<T> child)
{
AddItem((BinaryTree<T>)child);
}
/// <inheritdoc />
ITree<T> ITree<T>.GetChild(int index)
{
return GetChild(index);
}
/// <inheritdoc />
bool ITree<T>.Remove(ITree<T> child)
{
return Remove((BinaryTree<T>)child);
}
/// <inheritdoc />
ITree<T> ITree<T>.FindNode(Predicate<T> condition)
{
return FindNode(condition);
}
/// <inheritdoc />
ITree<T> ITree<T>.Parent => Parent;
#endregion
#region Public Members
/// <summary>
/// Gets the parent of the current node..
/// </summary>
/// <value>The parent of the current node.</value>
public BinaryTree<T> Parent { get; private set; }
/// <summary>
/// Finds the node with the specified condition. If a node is not found matching
/// the specified condition, null is returned.
/// </summary>
/// <param name="condition">The condition to test.</param>
/// <returns>The first node that matches the condition supplied. If a node is not found, null is returned.</returns>
/// <exception cref="ArgumentNullException"><paramref name="condition"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public BinaryTree<T> FindNode(Predicate<T> condition)
{
Guard.ArgumentNotNull(condition, "condition");
if (condition(Data))
{
return this;
}
if (_leftSubtree != null)
{
var ret = _leftSubtree.FindNode(condition);
if (ret != null)
{
return ret;
}
}
if (_rightSubtree != null)
{
var ret = _rightSubtree.FindNode(condition);
if (ret != null)
{
return ret;
}
}
return null;
}
/// <summary>
/// Gets or sets the left subtree.
/// </summary>
/// <value>The left subtree.</value>
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual BinaryTree<T> Left
{
get
{
return _leftSubtree;
}
set
{
if (_leftSubtree != null)
{
RemoveLeft();
}
if (value != null)
{
if (value.Parent != null)
{
value.Parent.Remove(value);
}
value.Parent = this;
}
_leftSubtree = value;
}
}
/// <summary>
/// Gets or sets the right subtree.
/// </summary>
/// <value>The right subtree.</value>
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual BinaryTree<T> Right
{
get
{
return _rightSubtree;
}
set
{
if (_rightSubtree != null)
{
RemoveRight();
}
if (value != null)
{
if (value.Parent != null)
{
value.Parent.Remove(value);
}
value.Parent = this;
}
_rightSubtree = value;
}
}
/// <inheritdoc />
public virtual T Data
{
get
{
return _data;
}
set
{
#region Validation
Guard.ArgumentNotNull(value, "data");
#endregion
_data = value;
}
}
/// <inheritdoc />
public int Degree => Count;
/// <summary>
/// Gets the child at the specified index.
/// </summary>
/// <param name="index">The index of the child in question.</param>
/// <returns>The child at the specified index.</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> does not equal 0 or 1.</exception>
public BinaryTree<T> GetChild(int index)
{
switch (index)
{
case 0:
return _leftSubtree;
case 1:
return _rightSubtree;
default:
throw new ArgumentOutOfRangeException("index");
}
}
/// <inheritdoc />
public virtual int Height
{
get
{
if (Degree == 0)
{
return 0;
}
return 1 + FindMaximumChildHeight();
}
}
/// <summary>
/// Performs a depth first traversal on this tree with the specified visitor.
/// </summary>
/// <param name="orderedVisitor">The ordered visitor.</param>
/// <exception cref="ArgumentNullException"><paramref name="orderedVisitor"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public virtual void DepthFirstTraversal(OrderedVisitor<T> orderedVisitor)
{
Guard.ArgumentNotNull(orderedVisitor, "orderedVisitor");
if (orderedVisitor.HasCompleted)
{
return;
}
// Preorder visit
orderedVisitor.VisitPreOrder(Data);
if (_leftSubtree != null)
{
_leftSubtree.DepthFirstTraversal(orderedVisitor);
}
// In-order visit
orderedVisitor.VisitInOrder(_data);
if (_rightSubtree != null)
{
_rightSubtree.DepthFirstTraversal(orderedVisitor);
}
// PostOrder visit
orderedVisitor.VisitPostOrder(Data);
}
/// <summary>
/// Performs a breadth first traversal on this tree with the specified visitor.
/// </summary>
/// <param name="visitor">The visitor.</param>
/// <exception cref="ArgumentNullException"><paramref name="visitor"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public virtual void BreadthFirstTraversal(IVisitor<T> visitor)
{
Guard.ArgumentNotNull(visitor, "visitor");
var queue = new Queue<BinaryTree<T>>();
queue.Enqueue(this);
while (queue.Count > 0)
{
if (visitor.HasCompleted)
{
break;
}
var binaryTree = queue.Dequeue();
visitor.Visit(binaryTree.Data);
for (var i = 0; i < binaryTree.Degree; i++)
{
var child = binaryTree.GetChild(i);
if (child != null)
{
queue.Enqueue(child);
}
}
}
}
/// <inheritdoc />
public virtual bool IsLeafNode => Degree == 0;
/// <summary>
/// Removes the left child.
/// </summary>
public virtual void RemoveLeft()
{
if (_leftSubtree != null)
{
_leftSubtree.Parent = null;
_leftSubtree = null;
}
}
/// <summary>
/// Removes the left child.
/// </summary>
public virtual void RemoveRight()
{
if (_rightSubtree != null)
{
_rightSubtree.Parent = null;
_rightSubtree = null;
}
}
/// <summary>
/// Adds an item to the <see cref="ICollection{T}"/>.
/// </summary>
/// <param name="subtree">The subtree.</param>
/// <exception cref="NotSupportedException">The <see cref="ICollection{T}"/> is read-only.</exception>
/// <exception cref="InvalidOperationException">The <see cref="BinaryTree{T}"/> is full.</exception>
/// <exception cref="ArgumentNullException"><paramref name="subtree"/> is null (Nothing in Visual Basic).</exception>
public void Add(BinaryTree<T> subtree)
{
Guard.ArgumentNotNull(subtree, "subtree");
AddItem(subtree);
}
/// <summary>
/// Adds an item to the <see cref="ICollection{T}"/>.
/// </summary>
/// <param name="subtree">The subtree.</param>
/// <remarks>
/// <b>Notes to Inheritors: </b>
/// Derived classes can override this method to change the behavior of the <see cref="Clear"/> method.
/// </remarks>
protected virtual void AddItem(BinaryTree<T> subtree)
{
if (_leftSubtree == null)
{
if (subtree.Parent != null)
{
subtree.Parent.Remove(subtree);
}
_leftSubtree = subtree;
subtree.Parent = this;
}
else if (_rightSubtree == null)
{
if (subtree.Parent != null)
{
subtree.Parent.Remove(subtree);
}
_rightSubtree = subtree;
subtree.Parent = this;
}
else
{
throw new InvalidOperationException("This binary tree is full.");
}
}
#endregion
#region Private Members
/// <summary>
/// Finds the maximum height between the child nodes.
/// </summary>
/// <returns>The maximum height of the tree between all paths from this node and all leaf nodes.</returns>
protected virtual int FindMaximumChildHeight()
{
var leftHeight = 0;
var rightHeight = 0;
if (_leftSubtree != null)
{
leftHeight = _leftSubtree.Height;
}
if (_rightSubtree != null)
{
rightHeight = _rightSubtree.Height;
}
return leftHeight > rightHeight ? leftHeight : rightHeight;
}
#endregion
#region Operator Overloads
/// <summary>
/// Gets the <see cref="BinaryTree{T}"/> at the specified index.
/// </summary>
public BinaryTree<T> this[int index] => GetChild(index);
#endregion
#region ICollection<T> Members
/// <inheritdoc />
public bool IsReadOnly => false;
#endregion
#region IEnumerable Members
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
#region Object Members
/// <inheritdoc />
public override string ToString()
{
return _data.ToString();
}
#endregion
}
}

68
src/NGenerics/DataStructures/Trees/ISearchTree.cs

@ -1,68 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Patterns.Visitor;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An interface for Search Trees that mimic a dictionary.
/// </summary>
/// <typeparam name="T">The type of element to hold in the tree.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
public interface ISearchTree<T> : ICollection<T>
{
/// <summary>
/// Gets the largest item in the tree.
/// </summary>
/// <value>The largest item in the tree.</value>
/// <exception cref="InvalidOperationException">The <see cref="ISearchTree{T}"/> is empty.</exception>
T Maximum { get; }
/// <summary>
/// Gets the smallest item in the tree.
/// </summary>
/// <value>The smallest item in the tree.</value>
/// <exception cref="InvalidOperationException">The <see cref="ISearchTree{T}"/> is empty.</exception>
T Minimum { get; }
/// <summary>
/// Performs a depth first traversal on the search tree.
/// </summary>
/// <param name="visitor">The visitor to use.</param>
/// <exception cref="ArgumentNullException"><paramref name="visitor"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="DepthFirstTraversal" lang="cs" title="The following example shows how to use the DepthFirstTraversal method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="DepthFirstTraversal" lang="vbnet" title="The following example shows how to use the DepthFirstTraversal method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
void DepthFirstTraversal(OrderedVisitor<T> visitor);
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
/// </returns>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="GetOrderedEnumerator" lang="cs" title="The following example shows how to use the GetOrderedEnumerator method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="GetOrderedEnumerator" lang="vbnet" title="The following example shows how to use the GetOrderedEnumerator method."/>
/// </example>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IEnumerator<T> GetOrderedEnumerator();
}
}

82
src/NGenerics/DataStructures/Trees/ITree.cs

@ -1,82 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An interface for the tree data structure
/// </summary>
/// <typeparam name="T">The type of elements in the tree.</typeparam>
public interface ITree<T>
{
/// <summary>
/// Adds the specified child to the tree.
/// </summary>
/// <param name="child">The child to add..</param>
void Add(ITree<T> child);
/// <summary>
/// Gets the data held in this node.
/// </summary>
/// <value>The data.</value>
T Data { get; }
/// <summary>
/// Gets the degree of this node.
/// </summary>
/// <value>The degree of this node.</value>
int Degree { get; }
/// <summary>
/// Gets the child at the specified index.
/// </summary>
/// <param name="index">The index.</param>
/// <returns>The child at the specified index.</returns>
ITree<T> GetChild(int index);
/// <summary>
/// Gets the height of this tree.
/// </summary>
/// <value>The height of this tree.</value>
int Height { get; }
/// <summary>
/// Gets a value indicating whether this instance is leaf node.
/// </summary>
/// <value>
/// <c>true</c> if this instance is leaf node; otherwise, <c>false</c>.
/// </value>
bool IsLeafNode { get; }
/// <summary>
/// Removes the specified child.
/// </summary>
/// <param name="child">The child.</param>
/// <returns>An indication of whether the child was found (and removed) from this tree.</returns>
bool Remove(ITree<T> child);
/// <summary>
/// Finds the node for which the given predicate holds true.
/// </summary>
/// <param name="condition">The condition to test on the data item.</param>
/// <returns>The fist node that matches the condition if found, otherwise null.</returns>
ITree<T> FindNode(Predicate<T> condition);
/// <summary>
/// Gets the parent of the current node.
/// </summary>
/// <value>The parent of the current node.</value>
ITree<T> Parent { get; }
}
}

21
src/NGenerics/DataStructures/Trees/NodeColor.cs

@ -1,21 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.DataStructures.Trees
{
internal enum NodeColor
{
Red = 0,
Black = 1
}
}

291
src/NGenerics/DataStructures/Trees/RedBlackTree.cs

@ -1,291 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
/*
* The insertion and deletion code is based on the code found at http://eternallyconfuzzled.com/tuts/redblack.htm.
* It's an excellent tutorial - if you want to understand Red Black trees, look there first.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An implementation of a Red-Black tree.
/// </summary>
/// <typeparam name="T">The type of element to keep in the tree.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
//[Serializable]
public class RedBlackTree<T> : BinarySearchTreeBase<T>
{
#region Construction
/// <inheritdoc />
public RedBlackTree()
{
// Do nothing - the default Comparer will be used by the base class.
}
/// <inheritdoc/>
public RedBlackTree(IComparer<T> comparer)
: base(comparer)
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTree(Comparison<T> comparison)
: base(comparison)
{
// Do nothing else.
}
#endregion
#region Public Members
/// <summary>
/// Adds an element with the provided key and value to the <see cref="IDictionary{TKey,TValue}"/>.
/// </summary>
/// <param name="item">The item.</param>
protected override void AddItem(T item)
{
#region Validation
if (Equals(item, null))
{
throw new ArgumentNullException("item");
}
#endregion
var root = (RedBlackTreeNode<T>)Tree;
var newRoot = InsertNode(root, item);
newRoot.Color = NodeColor.Black;
Tree = newRoot;
}
/// <summary>
/// Removes the element with the specified key from the <see cref="IDictionary{TKey,TValue}"/>.
/// </summary>
/// <param name="item">The item to remove.</param>
/// <returns>
/// <c>true</c> if the element is successfully removed; otherwise, <c>false</c>. This method also returns false if key was not found in the original <see cref="IDictionary{TKey,TValue}"/>.
/// </returns>
/// <inheritdoc/>
protected override bool RemoveItem(T item)
{
if (Tree != null)
{
var startNode = new RedBlackTreeNode<T>(default(T));
var childNode = startNode;
startNode.Right = (RedBlackTreeNode<T>)Tree;
RedBlackTreeNode<T> parent = null;
RedBlackTreeNode<T> foundNode = null;
var direction = true;
while (childNode[direction] != null)
{
var lastDirection = direction;
var grandParent = parent;
parent = childNode;
childNode = childNode[direction];
var comparisonValue = Comparer.Compare(childNode.Data, item);
if (comparisonValue == 0)
{
foundNode = childNode;
}
direction = comparisonValue < 0;
if ((IsBlack(childNode)) && (IsBlack(childNode[direction])))
{
if (IsRed(childNode[!direction]))
{
parent = parent[lastDirection] = SingleRotation(childNode, direction);
}
else if (IsBlack(childNode[direction]))
{
var sibling = parent[!lastDirection];
if (sibling != null)
{
if ((IsBlack(sibling.Left)) && (IsBlack(sibling.Right)))
{
parent.Color = NodeColor.Black;
sibling.Color = NodeColor.Red;
childNode.Color = NodeColor.Red;
}
else
{
var parentDirection = grandParent.Right == parent;
if (IsRed(sibling[lastDirection]))
{
grandParent[parentDirection] = DoubleRotation(parent, lastDirection);
}
else if (IsRed(sibling[!lastDirection]))
{
grandParent[parentDirection] = SingleRotation(parent, lastDirection);
}
childNode.Color = grandParent[parentDirection].Color = NodeColor.Red;
grandParent[parentDirection].Left.Color = NodeColor.Black;
grandParent[parentDirection].Right.Color = NodeColor.Black;
}
}
}
}
}
if (foundNode != null)
{
foundNode.Data = childNode.Data;
parent[parent.Right == childNode] = childNode[childNode.Left == null];
}
Tree = startNode.Right;
if (Tree != null)
{
((RedBlackTreeNode<T>)Tree).Color = NodeColor.Black;
}
if (foundNode != null)
{
return true;
}
}
return false;
}
#endregion
#region Private Members
/// <summary>
/// Determines whether the specified node is red.
/// </summary>
/// <param name="node">The node.</param>
/// <returns>
/// <c>true</c> if the specified node is red; otherwise, <c>false</c>.
/// </returns>
private static bool IsRed(RedBlackTreeNode<T> node)
{
return (node != null) && (node.Color == NodeColor.Red);
}
/// <summary>
/// Determines whether the specified node is black.
/// </summary>
/// <param name="node">The node.</param>
/// <returns>
/// <c>true</c> if the specified node is black; otherwise, <c>false</c>.
/// </returns>
private static bool IsBlack(RedBlackTreeNode<T> node)
{
return (node == null) || (node.Color == NodeColor.Black);
}
/// <summary>
/// A recursive implementation of insertion of a node into the tree.
/// </summary>
/// <param name="node">The start node.</param>
/// <param name="item">The item.</param>
/// <returns>The node created in the insertion.</returns>
private RedBlackTreeNode<T> InsertNode(RedBlackTreeNode<T> node, T item)
{
if (node == null)
{
node = new RedBlackTreeNode<T>(item);
}
else if (Comparer.Compare(item, node.Data) != 0)
{
var direction = Comparer.Compare(node.Data, item) < 0;
node[direction] = InsertNode(node[direction], item);
if (IsRed(node[direction]))
{
if (IsRed(node[!direction]))
{
node.Color = NodeColor.Red;
node.Left.Color = NodeColor.Black;
node.Right.Color = NodeColor.Black;
}
else
{
if (IsRed(node[direction][direction]))
{
node = SingleRotation(node, !direction);
}
else if (IsRed(node[direction][!direction]))
{
node = DoubleRotation(node, !direction);
}
}
}
}
else
{
throw new ArgumentException(alreadyContainedInTheTree);
}
return node;
}
/// <summary>
/// Perform a single rotation on the node provided..
/// </summary>
/// <param name="node">The node on which to focus the rotation.</param>
/// <param name="direction">The direction of the rotation. If direction is equal to true, a right rotation is performed. Other wise, a left rotation.</param>
/// <returns>The new root of the cluster.</returns>
private static RedBlackTreeNode<T> SingleRotation(RedBlackTreeNode<T> node, bool direction)
{
var childSibling = node[!direction];
node[!direction] = childSibling[direction];
childSibling[direction] = node;
node.Color = NodeColor.Red;
childSibling.Color = NodeColor.Black;
return childSibling;
}
/// <summary>
/// Perform a double rotation on the node provided..
/// </summary>
/// <param name="node">The node on which to focus the rotation.</param>
/// <param name="direction">The direction of the rotation. If direction is equal to true, a right rotation is performed. Other wise, a left rotation.</param>
/// <returns>The new root of the cluster.</returns>
private static RedBlackTreeNode<T> DoubleRotation(RedBlackTreeNode<T> node, bool direction)
{
node[!direction] = SingleRotation(node[!direction], !direction);
return SingleRotation(node, direction);
}
#endregion
}
}

251
src/NGenerics/DataStructures/Trees/RedBlackTreeDictionary.cs

@ -1,251 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
/*
* The insertion and deletion code is based on the code found at http://eternallyconfuzzled.com/tuts/redblack.htm.
* It's an excellent tutorial - if you want to understand Red Black trees, look there first.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Comparers;
using NGenerics.Patterns.Visitor;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// An implementation of a Red-Black tree.
/// </summary>
/// <typeparam name="TKey">The type of the keys in the <see cref="RedBlackTree{TKey,TValue}"/>.</typeparam>
/// <typeparam name="TValue">The type of the values in the <see cref="RedBlackTree{TKey,TValue}"/>.</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
#if (!SILVERLIGHT && !WINDOWSPHONE)
//[Serializable]
#endif
public class RedBlackTree<TKey, TValue> : RedBlackTree<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue> // BinarySearchTreeBase<TKey, TValue>
{
#region Construction
/// <inheritdoc />
public RedBlackTree() : base(new KeyValuePairComparer<TKey, TValue>())
{
// Do nothing - the default Comparer will be used by the base class.
}
/// <inheritdoc/>
public RedBlackTree(IComparer<TKey> comparer)
: base(new KeyValuePairComparer<TKey, TValue>(comparer))
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTree(Comparison<TKey> comparison)
: base(new KeyValuePairComparer<TKey, TValue>(comparison))
{
// Do nothing else.
}
#endregion
#region Private Members
private RedBlackTreeNode<KeyValuePair<TKey, TValue>> FindNode(TKey key)
{
return base.FindNode(new KeyValuePair<TKey, TValue>(key, default(TValue))) as RedBlackTreeNode<KeyValuePair<TKey, TValue>>;
}
private bool Contains(KeyValuePair<TKey, TValue> item, bool checkValue)
{
var node = FindNode(item);
if ((node != null) && !checkValue)
{
return true;
}
return node != null && Equals(item.Value, node.Data.Value);
}
#endregion
#region IDictionary<TKey,TValue> Members
/// <summary>
/// Removes the element with the specified key from the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <param name="key">The key of the element to remove.</param>
/// <returns>
/// true if the element is successfully removed; otherwise, false. This method also returns false if <paramref name="key"/> was not found in the original <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key"/> is null.
/// </exception>
/// <exception cref="T:System.NotSupportedException">
/// The <see cref="T:System.Collections.Generic.IDictionary`2"/> is read-only.
/// </exception>
public bool Remove(TKey key)
{
return Remove(new KeyValuePair<TKey, TValue>(key, default(TValue)));
}
/// <summary>
/// Adds an element with the provided key and value to the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <param name="key">The object to use as the key of the element to add.</param>
/// <param name="value">The object to use as the value of the element to add.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key"/> is null.
/// </exception>
/// <exception cref="T:System.ArgumentException">
/// An element with the same key already exists in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </exception>
/// <exception cref="T:System.NotSupportedException">
/// The <see cref="T:System.Collections.Generic.IDictionary`2"/> is read-only.
/// </exception>
public void Add(TKey key, TValue value)
{
if (Equals(key, null))
{
throw new ArgumentNullException("key");
}
Add(new KeyValuePair<TKey, TValue>(key, value));
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.IDictionary`2"/> contains an element with the specified key.
/// </summary>
/// <param name="key">The key to locate in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.</param>
/// <returns>
/// true if the <see cref="T:System.Collections.Generic.IDictionary`2"/> contains an element with the key; otherwise, false.
/// </returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="key"/> is null.
/// </exception>
public bool ContainsKey(TKey key)
{
return Contains(new KeyValuePair<TKey, TValue>(key, default(TValue)), false);
}
/// <summary>
/// Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the keys of the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <value></value>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Keys" lang="cs" title="The following example shows how to use the Keys property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Keys" lang="vbnet" title="The following example shows how to use the Keys property."/>
/// </example>
public ICollection<TKey> Keys
{
get
{
// Get the keys in sorted order
var visitor = new KeyTrackingVisitor<TKey, TValue>();
var inOrderVisitor = new InOrderVisitor<KeyValuePair<TKey, TValue>>(visitor);
DepthFirstTraversal(inOrderVisitor);
return new ReadOnlyCollection<TKey>(visitor.TrackingList);
}
}
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="TryGetValue" lang="cs" title="The following example shows how to use the TryGetValue method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="TryGetValue" lang="vbnet" title="The following example shows how to use the TryGetValue method."/>
/// </example>
public bool TryGetValue(TKey key, out TValue value)
{
var node = FindNode(new KeyValuePair<TKey, TValue>(key, default(TValue)));
if (node == null)
{
value = default(TValue);
return false;
}
value = node.Data.Value;
return true;
}
/// <summary>
/// Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the values in the <see cref="T:System.Collections.Generic.IDictionary`2"/>.
/// </summary>
/// <value></value>
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Values" lang="cs" title="The following example shows how to use the Values property."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Values" lang="vbnet" title="The following example shows how to use the Values property."/>
/// </example>
public ICollection<TValue> Values
{
get
{
var visitor = new ValueTrackingVisitor<TKey, TValue>();
var inOrderVisitor = new InOrderVisitor<KeyValuePair<TKey, TValue>>(visitor);
DepthFirstTraversal(inOrderVisitor);
return new ReadOnlyCollection<TValue>(visitor.TrackingList);
}
}
/// <summary>
/// Gets or sets the value with the specified key.
/// </summary>
/// <value>The key of the item to set or get.</value>
public TValue this[TKey key]
{
get
{
var node = FindNode(key);
if (node == null)
{
throw new KeyNotFoundException("key");
}
return node.Data.Value;
}
set
{
var node = FindNode(key);
if (node == null)
{
throw new KeyNotFoundException("key");
}
node.Data = new KeyValuePair<TKey, TValue>(key, value);
}
}
#endregion
#region ICollection<KeyValuePair<TKey,TValue>> Members
/// <inheritdoc />
/// <example>
/// <code source="..\..\Source\Examples\ExampleLibraryCSharp\DataStructures\Trees\BinarySearchTreeBaseExamples.cs" region="Contains" lang="cs" title="The following example shows how to use the Contains method."/>
/// <code source="..\..\Source\Examples\ExampleLibraryVB\DataStructures\Trees\BinarySearchTreeBaseExamples.vb" region="Contains" lang="vbnet" title="The following example shows how to use the Contains method."/>
/// </example>
public override bool Contains(KeyValuePair<TKey, TValue> item)
{
return Contains(item, true);
}
#endregion
}
}

232
src/NGenerics/DataStructures/Trees/RedBlackTreeList.cs

@ -1,232 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// A RedBlack Tree list variant. Equivalent to <see cref="RedBlackTree{TKey,TValue}"/> where TValue is a <see cref="LinkedList{T}"/>.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
//[Serializable]
internal class RedBlackTreeList<TKey, TValue> : RedBlackTree<TKey, LinkedList<TValue>>
{
#region Delegates
private delegate bool NodeAction(TKey key, LinkedList<TValue> values);
#endregion
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="RedBlackTreeList&lt;TKey, TValue&gt;"/> class.
/// </summary>
/// <inheritdoc/>
public RedBlackTreeList()
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTreeList(IComparer<TKey> comparer)
: base(comparer)
{
// Do nothing else.
}
/// <inheritdoc/>
public RedBlackTreeList(Comparison<TKey> comparison)
: base(comparison)
{
// Do nothing else.
}
#endregion
#region Public Members
/// <summary>
/// Determines whether the specified value contains value.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// <c>true</c> if the specified value contains value; otherwise, <c>false</c>.
/// </returns>
public bool ContainsValue(TValue value)
{
return TraverseItems((key, list) => list.Contains(value));
}
/// <summary>
/// Gets the value enumerator.
/// </summary>
/// <returns>An enumerator to enumerate through the values contained in this instance.</returns>
public IEnumerator<TValue> GetValueEnumerator()
{
var stack = new Stack<BinaryTree<KeyValuePair<TKey, LinkedList<TValue>>>>();
if (Tree != null)
{
stack.Push(Tree);
}
while (stack.Count > 0)
{
var currentNode = stack.Pop();
var list = currentNode.Data.Value;
foreach (var item in list)
{
yield return item;
}
if (currentNode.Left != null)
{
stack.Push(currentNode.Left);
}
if (currentNode.Right != null)
{
stack.Push(currentNode.Right);
}
}
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="IEnumerator{T}"/> that can be used to iterate through the collection.
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IEnumerator<KeyValuePair<TKey, TValue>> GetKeyEnumerator()
{
var stack = new Stack<BinaryTree<KeyValuePair<TKey, LinkedList<TValue>>>>();
if (Tree != null)
{
stack.Push(Tree);
}
while (stack.Count > 0)
{
var currentNode = stack.Pop();
var list = currentNode.Data.Value;
foreach (var item in list)
{
yield return new KeyValuePair<TKey, TValue>(currentNode.Data.Key, item);
}
if (currentNode.Left != null)
{
stack.Push(currentNode.Left);
}
if (currentNode.Right != null)
{
stack.Push(currentNode.Right);
}
}
}
/// <summary>
/// Removes the specified value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="key">The key under which the item was found.</param>
/// <returns>A value indicating whether the item was found or not.</returns>
public bool Remove(TValue value, out TKey key)
{
var foundKey = default(TKey);
var ret = TraverseItems(
delegate (TKey itemKey, LinkedList<TValue> list)
{
if (list.Remove(value))
{
if (list.Count == 0)
{
Remove(itemKey);
}
foundKey = itemKey;
return true;
}
return false;
}
);
key = foundKey;
return ret;
}
#endregion
#region Private Members
/// <summary>
/// Traverses the items.
/// </summary>
/// <param name="shouldStop">A predicate that performs an action on the list, and indicates whether the enumeration of items should stop or not.</param>
/// <returns>An indication of whether the enumeration was stopped prematurely.</returns>
private bool TraverseItems(NodeAction shouldStop)
{
#region Validation
Debug.Assert(shouldStop != null);
#endregion
var stack = new Stack<BinaryTree<KeyValuePair<TKey, LinkedList<TValue>>>>();
if (Tree != null)
{
stack.Push(Tree);
}
while (stack.Count > 0)
{
var currentNode = stack.Pop();
if (shouldStop(currentNode.Data.Key, currentNode.Data.Value))
{
return true;
}
if (currentNode.Left != null)
{
stack.Push(currentNode.Left);
}
if (currentNode.Right != null)
{
stack.Push(currentNode.Right);
}
}
return false;
}
#endregion
}
}

107
src/NGenerics/DataStructures/Trees/RedBlackTreeNode.cs

@ -1,107 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Diagnostics.CodeAnalysis;
namespace NGenerics.DataStructures.Trees
{
/// <summary>
/// A container class, used for the RedBlackTree.
/// </summary>
/// <typeparam name="T">The type of element.</typeparam>
//[Serializable]
[SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
internal class RedBlackTreeNode<T> : BinaryTree<T>
{
#region Construction
/// <summary>
/// Initializes a new instance of the <see cref="RedBlackTreeNode&lt;T&gt;"/> class.
/// </summary>
/// <param name="data">The data contained in this node.</param>
internal RedBlackTreeNode(T data)
: base(data)
{
Color = NodeColor.Red;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the color of the current node.
/// </summary>
/// <value>The color of the node.</value>
internal NodeColor Color { get; set; }
/// <summary>
/// Gets or sets the <see cref="NGenerics.DataStructures.Trees.BinaryTree&lt;T&gt;"/> with the specified direction.
/// </summary>
/// <value></value>
internal RedBlackTreeNode<T> this[bool direction]
{
get
{
return direction ? Right : Left;
}
set
{
if (direction)
{
Right = value;
}
else
{
Left = value;
}
}
}
/// <summary>
/// Gets or sets the left subtree.
/// </summary>
/// <value>The left subtree.</value>
internal new RedBlackTreeNode<T> Left
{
get
{
return (RedBlackTreeNode<T>)base.Left;
}
set
{
base.Left = value;
}
}
/// <summary>
/// Gets or sets the right subtree.
/// </summary>
/// <value>The right subtree.</value>
internal new RedBlackTreeNode<T> Right
{
get
{
return (RedBlackTreeNode<T>)base.Right;
}
set
{
base.Right = value;
}
}
#endregion
}
}

76
src/NGenerics/NGenerics.csproj

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{415E048E-4611-4815-9CF2-D774E29079AC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NGenerics</RootNamespace>
<AssemblyName>NGenerics</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup>
<Compile Include="DataStructures\Comparers\ReverseComparer.cs" />
<Compile Include="DataStructures\General\Heap.cs" />
<Compile Include="DataStructures\General\HeapType.cs" />
<Compile Include="DataStructures\General\IHeap.cs" />
<Compile Include="DataStructures\Trees\BinarySearchTreeBase.cs" />
<Compile Include="DataStructures\Trees\BinaryTree.cs" />
<Compile Include="DataStructures\Comparers\ComparisonComparer.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Util\Guard.cs" />
<Compile Include="Patterns\Visitor\InOrderVisitor.cs" />
<Compile Include="DataStructures\Queues\IQueue.cs" />
<Compile Include="DataStructures\Trees\ISearchTree.cs" />
<Compile Include="DataStructures\Trees\ITree.cs" />
<Compile Include="Patterns\Visitor\IVisitor.cs" />
<Compile Include="Patterns\Visitor\KeyTrackingVisitor.cs" />
<Compile Include="DataStructures\Comparers\KeyValuePairComparer.cs" />
<Compile Include="DataStructures\Trees\NodeColor.cs" />
<Compile Include="Patterns\Visitor\OrderedVisitor.cs" />
<Compile Include="DataStructures\Queues\PriorityQueue.cs" />
<Compile Include="DataStructures\Queues\PriorityQueueType.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="DataStructures\Trees\RedBlackTree.cs" />
<Compile Include="DataStructures\Trees\RedBlackTreeDictionary.cs" />
<Compile Include="DataStructures\Trees\RedBlackTreeList.cs" />
<Compile Include="DataStructures\Trees\RedBlackTreeNode.cs" />
<Compile Include="Patterns\Visitor\TrackingVisitor.cs" />
<Compile Include="Patterns\Visitor\ValueTrackingVisitor.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

34
src/NGenerics/Patterns/Visitor/IVisitor.cs

@ -1,34 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// Provides an interface for visitors.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public interface IVisitor<T>
{
/// <summary>
/// Gets a value indicating whether this instance is done performing it's work..
/// </summary>
/// <value><c>true</c> if this instance is done; otherwise, <c>false</c>.</value>
bool HasCompleted { get; }
/// <summary>
/// Visits the specified object.
/// </summary>
/// <param name="obj">The object to visit.</param>
void Visit(T obj);
}
}

51
src/NGenerics/Patterns/Visitor/InOrderVisitor.cs

@ -1,51 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// An in order implementation of the <see cref="OrderedVisitor{T}"/> class.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public sealed class InOrderVisitor<T> : OrderedVisitor<T>
{
#region Construction
/// <param name="visitor">The visitor.</param>
public InOrderVisitor(IVisitor<T> visitor) : base(visitor) { }
#endregion
#region OrderedVisitor<T> Members
/// <summary>
/// Visits the object in post order.
/// </summary>
/// <param name="obj">The obj.</param>
public override void VisitPostOrder(T obj)
{
// Do nothing.
}
/// <summary>
/// Visits the object in pre order.
/// </summary>
/// <param name="obj">The obj.</param>
public override void VisitPreOrder(T obj)
{
// Do nothing.
}
#endregion
}
}

65
src/NGenerics/Patterns/Visitor/KeyTrackingVisitor.cs

@ -1,65 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System.Collections.Generic;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that tracks (stores) keys from KeyValuePAirs in the order they were visited.
/// </summary>
/// <typeparam name="TKey">The type of the keys for the items to be visited.</typeparam>
/// <typeparam name="TValue">The type of the values for the items to be visited.</typeparam>
public sealed class KeyTrackingVisitor<TKey, TValue> : IVisitor<KeyValuePair<TKey, TValue>>
{
#region Globals
private readonly List<TKey> _tracks;
#endregion
#region Construction
/// <inheritdoc/>
public KeyTrackingVisitor()
{
_tracks = new List<TKey>();
}
#endregion
#region Public Members
/// <summary>
/// Gets the tracking list.
/// </summary>
/// <value>The tracking list.</value>
public IList<TKey> TrackingList => _tracks;
#endregion
#region IVisitor<KeyValuePair<TKey,TValue>> Members
/// <inheritdoc />
public void Visit(KeyValuePair<TKey, TValue> obj)
{
_tracks.Add(obj.Key);
}
/// <inheritdoc />
public bool HasCompleted => false;
#endregion
}
}

102
src/NGenerics/Patterns/Visitor/OrderedVisitor.cs

@ -1,102 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
using System.Diagnostics.CodeAnalysis;
using NGenerics.Util;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that visits objects in order (PreOrder, PostOrder, or InOrder).
/// Used primarily as a base class for Visitors specializing in a specific order type.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public class OrderedVisitor<T> : IVisitor<T>
{
#region Globals
private readonly IVisitor<T> _visitorToUse;
#endregion
#region Construction
/// <param name="visitorToUse">The visitor to use when visiting the object.</param>
/// <exception cref="ArgumentNullException"><paramref name="visitorToUse"/> is a null reference (<c>Nothing</c> in Visual Basic).</exception>
public OrderedVisitor(IVisitor<T> visitorToUse)
{
Guard.ArgumentNotNull(visitorToUse, "visitorToUse");
_visitorToUse = visitorToUse;
}
#endregion
#region IOrderedVisitor<T> Members
/// <summary>
/// Determines whether this visitor is done.
/// </summary>
/// <value></value>
/// <returns>
/// <c>true</c> if this visitor is done; otherwise, <c>false</c>.
/// </returns>
public bool HasCompleted => _visitorToUse.HasCompleted;
/// <summary>
/// Visits the object in pre order.
/// </summary>
/// <param name="obj">The obj.</param>
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "PreOrder")]
public virtual void VisitPreOrder(T obj)
{
_visitorToUse.Visit(obj);
}
/// <summary>
/// Visits the object in post order.
/// </summary>
/// <param name="obj">The obj.</param>
public virtual void VisitPostOrder(T obj)
{
_visitorToUse.Visit(obj);
}
/// <summary>
/// Visits the object in order.
/// </summary>
/// <param name="obj">The obj.</param>
public virtual void VisitInOrder(T obj)
{
_visitorToUse.Visit(obj);
}
/// <inheritdoc />
public void Visit(T obj)
{
_visitorToUse.Visit(obj);
}
#endregion
#region Public Members
/// <summary>
/// Gets the visitor to use.
/// </summary>
/// <value>The visitor to use.</value>
public IVisitor<T> VisitorToUse => _visitorToUse;
#endregion
}
}

65
src/NGenerics/Patterns/Visitor/TrackingVisitor.cs

@ -1,65 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System.Collections.Generic;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that tracks (stores) objects in the order they were visited.
/// Handy for demonstrating and testing different ordered visits implementations on
/// data structures.
/// </summary>
/// <typeparam name="T">The type of objects to be visited.</typeparam>
public sealed class TrackingVisitor<T> : IVisitor<T>
{
#region Globals
private readonly List<T> _tracks;
#endregion
#region Construction
/// <inheritdoc/>
public TrackingVisitor()
{
_tracks = new List<T>();
}
#endregion
#region IVisitor<T> Members
/// <inheritdoc />
public void Visit(T obj)
{
_tracks.Add(obj);
}
/// <inheritdoc />
public bool HasCompleted => false;
#endregion
#region Public Members
/// <summary>
/// Gets the tracking list.
/// </summary>
/// <value>The tracking list.</value>
public IList<T> TrackingList => _tracks;
#endregion
}
}

66
src/NGenerics/Patterns/Visitor/ValueTrackingVisitor.cs

@ -1,66 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System.Collections.Generic;
namespace NGenerics.Patterns.Visitor
{
/// <summary>
/// A visitor that tracks (stores) keys from KeyValuePairs in the order they were visited.
/// </summary>
/// <typeparam name="TKey">The type of key of the KeyValuePair.</typeparam>
/// <typeparam name="TValue">The type of value of the KeyValuePair.</typeparam>
public sealed class ValueTrackingVisitor<TKey, TValue> : IVisitor<KeyValuePair<TKey, TValue>>
{
#region Globals
private readonly List<TValue> _tracks;
#endregion
#region Construction
/// <inheritdoc/>
public ValueTrackingVisitor()
{
_tracks = new List<TValue>();
}
#endregion
#region Public Members
/// <summary>
/// Gets the tracking list.
/// </summary>
/// <value>The tracking list.</value>
public IList<TValue> TrackingList => _tracks;
#endregion
#region IVisitor<KeyValuePair<TKey,TValue>> Members
/// <inheritdoc />
public void Visit(KeyValuePair<TKey, TValue> obj)
{
_tracks.Add(obj.Value);
}
/// <inheritdoc />
public bool HasCompleted => false;
#endregion
}
}

33
src/NGenerics/Properties/AssemblyInfo.cs

@ -1,33 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("NGenerics")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NGenerics")]
[assembly: AssemblyCopyright("Copyright \u00A9 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

59
src/NGenerics/Util/Guard.cs

@ -1,59 +0,0 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
/*
Copyright 2007-2013 The NGenerics Team
(https://github.com/ngenerics/ngenerics/wiki/Team)
This program is licensed under the GNU Lesser General Public License (LGPL). You should
have received a copy of the license along with the source code. If not, an online copy
of the license can be found at http://www.gnu.org/copyleft/lesser.html.
*/
using System;
namespace NGenerics.Util
{
/// <summary>
/// Performs common argument validation.
/// </summary>
public static class Guard
{
#region Methods
/// <summary>
/// Checks a string argument to ensure it isn't null or empty.
/// </summary>
/// <param name="argumentValue">The argument value to check.</param>
/// <param name="argumentName">The name of the argument.</param>
/// <exception cref="ArgumentNullException"><paramref name="argumentValue"/> is a null reference.</exception>
/// <exception cref="ArgumentException"><paramref name="argumentValue"/> is <see cref="string.Empty"/>.</exception>
public static void ArgumentNotNullOrEmptyString(string argumentValue, string argumentName)
{
ArgumentNotNull(argumentValue, argumentName);
if (argumentValue.Length == 0)
{
throw new ArgumentException("String cannot be empty.", argumentName);
}
}
/// <summary>
/// Checks an argument to ensure it isn't null.
/// </summary>
/// <param name="argumentValue">The argument value to check.</param>
/// <param name="argumentName">The name of the argument.</param>
/// <exception cref="ArgumentNullException"><paramref name="argumentValue"/> is a null reference.</exception>
public static void ArgumentNotNull(object argumentValue, string argumentName)
{
if (argumentValue == null)
{
throw new ArgumentNullException(argumentName);
}
}
#endregion
}
}

6
src/Perspex.Base/Perspex.Base.csproj

@ -101,12 +101,6 @@
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

8
src/Perspex.Base/Threading/MainLoop.cs

@ -2,9 +2,9 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using NGenerics.DataStructures.Queues;
using Perspex.Platform;
using Perspex.Threading;
using Splat;
@ -18,8 +18,7 @@ namespace Perspex.Win32.Threading
{
private static readonly IPlatformThreadingInterface s_platform;
private readonly PriorityQueue<Job, DispatcherPriority> _queue =
new PriorityQueue<Job, DispatcherPriority>(PriorityQueueType.Maximum);
private readonly Queue<Job> _queue = new Queue<Job>();
/// <summary>
/// Initializes static members of the <see cref="MainLoop"/> class.
@ -109,6 +108,7 @@ namespace Perspex.Win32.Threading
/// <param name="priority">The priority with which to invoke the method.</param>
internal void Post(Action action, DispatcherPriority priority)
{
// TODO: Respect priority.
AddJob(new Job(action, priority, true));
}
@ -116,7 +116,7 @@ namespace Perspex.Win32.Threading
{
lock (_queue)
{
_queue.Add(job, job.Priority);
_queue.Enqueue(job);
}
s_platform.Wake();
}

16
src/Perspex.Layout/LayoutManager.cs

@ -2,10 +2,10 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using NGenerics.DataStructures.General;
using Perspex.VisualTree;
using Serilog;
using Serilog.Core.Enrichers;
@ -44,14 +44,14 @@ namespace Perspex.Layout
private bool _measureNeeded = true;
/// <summary>
/// The controls that need to be measured, sorted by distance to layout root.
/// The controls that need to be measured.
/// </summary>
private Heap<Item> _toMeasure = new Heap<Item>(HeapType.Minimum);
private List<Item> _toMeasure = new List<Item>();
/// <summary>
/// The controls that need to be arranged, sorted by distance to layout root.
/// The controls that need to be arranged.
/// </summary>
private Heap<Item> _toArrange = new Heap<Item>(HeapType.Minimum);
private List<Item> _toArrange = new List<Item>();
/// <summary>
/// Prevents re-entrancy.
@ -207,7 +207,8 @@ namespace Perspex.Layout
{
var measure = _toMeasure;
_toMeasure = new Heap<Item>(HeapType.Minimum);
_toMeasure = new List<Item>();
measure.Sort();
if (!Root.IsMeasureValid)
{
@ -254,7 +255,8 @@ namespace Perspex.Layout
{
var arrange = _toArrange;
_toArrange = new Heap<Item>(HeapType.Minimum);
_toArrange = new List<Item>();
arrange.Sort();
if (!Root.IsArrangeValid && Root.IsMeasureValid)
{

4
src/Perspex.Layout/Perspex.Layout.csproj

@ -39,10 +39,6 @@
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<ProjectReference Include="..\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
<ProjectReference Include="..\Perspex.Animation\Perspex.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Perspex.Animation</Name>

4
tests/Perspex.Interactivity.UnitTests/Perspex.Interactivity.UnitTests.csproj

@ -64,10 +64,6 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Perspex.Animation\Perspex.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Perspex.Animation</Name>

4
tests/Perspex.Layout.UnitTests/Perspex.Layout.UnitTests.csproj

@ -76,10 +76,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Perspex.Animation\Perspex.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Perspex.Animation</Name>

4
tests/Perspex.Markup.Xaml.UnitTests/Perspex.Markup.Xaml.UnitTests.csproj

@ -113,10 +113,6 @@
<Project>{3E53A01A-B331-47F3-B828-4A5717E77A24}</Project>
<Name>Perspex.Markup.Xaml</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\NGenerics\NGenerics.csproj">
<Project>{415E048E-4611-4815-9CF2-D774E29079AC}</Project>
<Name>NGenerics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Perspex.Animation\Perspex.Animation.csproj">
<Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
<Name>Perspex.Animation</Name>

Loading…
Cancel
Save