using System.Collections.Generic;
namespace Collections
{
///
/// 双方向連結リスト。
///
/// 要素の型
public class LinkedList : IEnumerable
{
#region 内部クラス
///
/// 連結リストのノード。
///
public class Node
{
#region フィールド
T val;
Node prev;
Node next;
#endregion
#region 初期化
internal Node(T val, Node prev, Node next)
{
this.val = val;
this.prev = prev;
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; }
}
///
/// 次のノード。
///
public Node Previous
{
get { return this.prev; }
internal set { this.prev = value; }
}
#endregion
}
#endregion
#region フィールド
Node dummy;
#endregion
#region 初期化
public LinkedList()
{
this.dummy = new Node(default(T), null, null);
this.dummy.Next = this.dummy;
this.dummy.Previous = this.dummy;
}
#endregion
#region プロパティ
///
/// リストの先頭ノード。
///
public Node First
{
get { return this.dummy.Next; }
}
///
/// リストの末尾ノード。
///
public Node Last
{
get { return this.dummy.Previous; }
}
///
/// リストの終端(末尾よりも後ろの番兵に当たるノード)。
///
public Node End
{
get { return this.dummy; }
}
///
/// 要素の個数。
///
public int Count
{
get
{
int i = 0;
for (Node n = this.First; n != this.End; n = n.Next)
++i;
return i;
}
}
#endregion
#region 挿入・削除
///
/// ノード n の後ろに新しい要素を追加。
///
/// 要素の挿入位置
/// 新しい要素
/// 新しく挿入されたノード
public Node InsertAfter(Node n, T elem)
{
Node m = new Node(elem, n, n.Next);
n.Next.Previous = m;
n.Next = m;
return m;
}
///
/// ノード n の前に新しい要素を追加。
///
/// 要素の挿入位置
/// 新しい要素
/// 新しく挿入されたノード
public Node InsertBefore(Node n, T elem)
{
Node m = new Node(elem, n.Previous, n);
n.Previous.Next = m;
n.Previous = m;
return m;
}
///
/// 先頭に新しい要素を追加。
///
/// 新しい要素
/// 新しく挿入されたノード
public Node InsertFirst(T elem)
{
return this.InsertAfter(this.dummy, elem);
}
///
/// 末尾に新しい要素を追加。
///
/// 新しい要素
/// 新しく挿入されたノード
public Node InsertLast(T elem)
{
return this.InsertBefore(this.dummy, elem);
}
///
/// ノード n の自身を削除。
///
/// 要素の削除位置
/// 削除した要素の次のノード
public Node Erase(Node n)
{
if (n == this.dummy)
{
return this.dummy;
}
n.Previous.Next = n.Next;
n.Next.Previous = n.Previous;
return n.Next;
}
///
/// 先頭の要素を削除。
///
public void EraseFirst()
{
this.Erase(this.First);
}
///
/// 末尾の要素を削除。
///
public void EraseLast()
{
this.Erase(this.Last);
}
#endregion
#region IEnumerable メンバ
public IEnumerator GetEnumerator()
{
for (Node n = this.First; n != this.End; n = n.Next)
yield return n.Value;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}