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 } }