基本クラス ライブラリの実装を使用せずに、C# で次のデータ構造を実装する方法を知りたいです。
- リンクされたリスト
- ハッシュ表
- 二分探索木
- 赤黒の木
- Bツリー
- 二項ヒープ
- フィボナッチヒープ
そして、人々が考えることができる他の基本的なデータ構造!
これらのデータ構造の理解を深めたいので興味があります。インターネットに出回っている典型的な C の例ではなく、C# のバージョンを参照してください。
基本クラス ライブラリの実装を使用せずに、C# で次のデータ構造を実装する方法を知りたいです。
そして、人々が考えることができる他の基本的なデータ構造!
これらのデータ構造の理解を深めたいので興味があります。インターネットに出回っている典型的な C の例ではなく、C# のバージョンを参照してください。
このテーマに関する一連のMSDN 記事があります。とはいえ、私自身はテキストをよく読んだことがありません。.NET によるコレクション フレームワークはインターフェイスが壊れていて、うまく拡張できないと思います。
私が現在調査しているライブラリであるC5もあります。
上記の理由により、私は .NET 用に独自のコレクション ライブラリを実装するプロジェクトを持っていましたが、最初のベンチマークで、単純でスレッドセーフでない一般的なVector
実装でさえネイティブよりも遅いことが明らかになった後、このプロジェクトを停止しました。 List<T>
. 非効率な IL コードを作成しないように注意したので、これは、.NET が (まだ) 組み込みデータ構造の同等の置換を作成するのに適していないことを意味し、.NET フレームワークは背後でいくつかのコードを使用する必要があることを意味します。 -組み込みのコレクション クラスを最適化するためのシーンの知識。
これが一般的な二分探索木です。私がしなかった唯一のことは、列挙子を使用してツリーをトラバースできるようにIEnumerable<T>を実装することでした。ただし、それはかなり簡単なはずです。
BSTTreeの記事を提供してくれたScottMitchelに特に感謝します。これを、deleteメソッドのリファレンスとして使用しました。
ノードクラス:
class BSTNode<T> where T : IComparable<T>
{
private BSTNode<T> _left = null;
private BSTNode<T> _right = null;
private T _value = default(T);
public T Value
{
get { return this._value; }
set { this._value = value; }
}
public BSTNode<T> Left
{
get { return _left; }
set { this._left = value; }
}
public BSTNode<T> Right
{
get { return _right; }
set { this._right = value; }
}
}
そして実際のTreeクラス:
class BinarySearchTree<T> where T : IComparable<T>
{
private BSTNode<T> _root = null;
private int _count = 0;
public virtual void Clear()
{
_root = null;
_count = 0;
}
public virtual int Count
{
get { return _count; }
}
public virtual void Add(T value)
{
BSTNode<T> newNode = new BSTNode<T>();
int compareResult = 0;
newNode.Value = value;
if (_root == null)
{
this._count++;
_root = newNode;
}
else
{
BSTNode<T> current = _root;
BSTNode<T> parent = null;
while (current != null)
{
compareResult = current.Value.CompareTo(newNode.Value);
if (compareResult > 0)
{
parent = current;
current = current.Left;
}
else if (compareResult < 0)
{
parent = current;
current = current.Right;
}
else
{
// Node already exists
throw new ArgumentException("Duplicate nodes are not allowed.");
}
}
this._count++;
compareResult = parent.Value.CompareTo(newNode.Value);
if (compareResult > 0)
{
parent.Left = newNode;
}
else
{
parent.Right = newNode;
}
}
}
public virtual BSTNode<T> FindByValue(T value)
{
BSTNode<T> current = this._root;
if (current == null)
return null; // Tree is empty.
else
{
while (current != null)
{
int result = current.Value.CompareTo(value);
if (result == 0)
{
// Found the corrent Node.
return current;
}
else if (result > 0)
{
current = current.Left;
}
else
{
current = current.Right;
}
}
return null;
}
}
public virtual void Delete(T value)
{
BSTNode<T> current = this._root;
BSTNode<T> parent = null;
int result = current.Value.CompareTo(value);
while (result != 0 && current != null)
{
if (result > 0)
{
parent = current;
current = current.Left;
}
else if (result < 0)
{
parent = current;
current = current.Right;
}
result = current.Value.CompareTo(value);
}
if (current == null)
throw new ArgumentException("Cannot find item to delete.");
if (current.Right == null)
{
if (parent == null)
this._root = current.Left;
else
{
result = parent.Value.CompareTo(current.Value);
if (result > 0)
{
parent.Left = current.Left;
}
else if (result < 0)
{
parent.Right = current.Left;
}
}
}
else if (current.Right.Left == null)
{
if (parent == null)
this._root = current.Right;
else
{
result = parent.Value.CompareTo(current.Value);
if (result > 0)
{
parent.Left = current.Right;
}
else if (result < 0)
{
parent.Right = current.Right;
}
}
}
else
{
BSTNode<T> furthestLeft = current.Right.Left;
BSTNode<T> furthestLeftParent = current.Right;
while (furthestLeft.Left != null)
{
furthestLeftParent = furthestLeft;
furthestLeft = furthestLeft.Left;
}
furthestLeftParent.Left = furthestLeft.Right;
furthestLeft.Left = current.Left;
furthestLeft.Right = current.Right;
if (parent != null)
{
result = parent.Value.CompareTo(current.Value);
if (result > 0)
{
parent.Left = furthestLeft;
}
else if (result < 0)
{
parent.Right = furthestLeft;
}
}
else
{
this._root = furthestLeft;
}
}
this._count--;
}
}
}
あなたが言及したデータ構造については、2 つのリソースをお勧めします。まず、.NET Framework のソース コードがあります (情報は、ScottGu のブログ (こちら) にあります)。
もう 1 つの便利なリソースは、ここの Codeplex にある Wintellect の Power Collectionsです。
お役に立てれば!
「標準の .NET フレームワークに実装されていない一般的なデータ構造とアルゴリズムを提供するクラス ライブラリ。」
Rotor 2をチェックするか、リフレクターを使用して、Microsoft がどのようにそれを行ったかを確認してください!!!
また、 Microsoftの参照元を確認することもできます