using System.Collections.Generic;
namespace Collections
{
///
/// 片方向連結リスト。
///
/// 要素の型
public class ForwardLinkedList : IEnumerable
{
#region 内部クラス
///
/// 片方向連結リストのノード。
///
public class Node
{
#region フィールド
T val;
Node next;
#endregion
#region 初期化
internal Node(T val, Node next)
{
this.val = val;
this.next = next;
}
#endregion
#region プロパティ
///
/// 格納している要素を取得。
///
public T Value
{
get { return this.val; }
set { this.val = value; }
}
///
/// 次のノード。
///
public Node Next
{
get { return this.next; }
internal set { this.next = value; }
}
#endregion
}
#endregion
#region フィールド
Node first;
#endregion
#region 初期化
public ForwardLinkedList()
{
this.first = null;
}
#endregion
#region プロパティ
///
/// リストの先頭ノード。
///
public Node First
{
get { return this.first; }
}
///
/// 要素の個数。
///
public int Count
{
get
{
int i = 0;
for(Node n = this.first; n!=null; n=n.Next)
++i;
return i;
}
}
#endregion
#region 挿入・削除
///
/// ノード n の後ろに新しい要素を追加。
///
/// 要素の挿入位置
/// 新しい要素
/// 新しく挿入されたノード
public Node InsertAfter(Node n, T elem)
{
Node m = new Node(elem, n.Next);
n.Next = m;
return m;
}
///
/// 先頭に新しい要素を追加。
///
/// 新しい要素
/// 新しく挿入されたノード
public Node InsertFirst(T elem)
{
Node m = new Node(elem, this.first);
this.first = m;
return m;
}
///
/// ノード n の後ろの要素を削除。
///
/// 要素の削除位置
public void EraseAfter(Node n)
{
if (n != null && n.Next != null)
n.Next = n.Next.Next;
}
///
/// ノード n の自身を削除。
///
/// 要素の削除位置
/// 削除した要素の次のノード
public Node Erase(Node n)
{
Node prev = this.first;
for (; prev != null && prev.Next != n; prev = prev.Next) ;
if (prev == this.first)
{
this.first = null;
return null;
}
if (prev != null)
{
this.EraseAfter(prev);
return prev.Next;
}
return null;
}
///
/// 先頭の要素を削除。
///
public void EraseFirst()
{
if (this.first != null)
this.first = this.first.Next;
}
#endregion
#region IEnumerable メンバ
public IEnumerator GetEnumerator()
{
for (Node n = this.first; n != null; n = n.Next)
yield return n.Value;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}