这个链表没有暴露node接口,而是把链表本身包装成了一个Collection和List,实现了ICollection<T>, IEnumerable<T>, IList<T>接口,写的过程中参考了BCL中的实现以及Wintellect.PowerCollection的实现以及写法。并且初步通过测试。
namespace FengChen.Practices
{
internal class ListNode<T>
{
public T Item; // Element item
public ListNode<T> Next;
internal ListNode() { this.Next = null; }
}
{
private ListNode<T> m_Head;
private ListNode<T> m_End;
private Int32 m_Count;
public LinkList()
{
m_Head = new ListNode<T>();
m_End = m_Head;
}
: this()
{
if (array == null) throw new ArgumentNullException("array");
foreach (T item in array) this.Add(item);
}
#endregion
public bool IsEmpty { get { return m_Head.Next == null; } }
{
ListNode<T> node = m_Head.Next;
index = 0;
{
node = node.Next;
index++;
}
if (node == null) index = -1;
return node;
}
{
ListNode<T> node = m_Head;
node = node.Next;
return node;
}
#endregion
public void Add(T item) // Add the item at end
{
ListNode<T> node = new ListNode<T>(item);
m_End.Next = node;
m_End = node;
m_Count++;
}
{
ListNode<T> pos, temp;
pos = m_Head;
while (pos != null)
{
temp = pos.Next;
pos.Next = null;
pos = temp;
}
m_Count = 0;
m_End = m_Head;
}
{
Int32 i = 0;
return this.Find(item, out i) != null;
}
{
if (array == null)
throw new ArgumentNullException("array");
if ((index < 0) || (index >= array.Length))
throw new ArgumentOutOfRangeException("index", index, "Please check the index value!");
if ((array.Length - index) < this.Count)
throw new ArgumentException("Insufficient Space!");
while(node != null)
{
array[index++] = node.Item;
node = node.Next;
}
}
{
ListNode<T> preNode = this.FindPrevious(item);
ListNode<T> tempNode = null;
if (preNode.Next != null) // item is found
{
if (m_End == preNode.Next) m_End = preNode;
tempNode = preNode.Next; // node to be deleted
preNode.Next = tempNode.Next;
tempNode = null;
m_Count--;
return true;
}
return false;
}
#endregion
public IEnumerator<T> GetEnumerator()
{
ListNode<T> node = this.m_Head.Next;
while(node != null)
{
yield return node.Item;
node = node.Next;
}
}
#endregion
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
/// StreamWriter = new StreamWriter(Console.OpenStandardOutput());
/// </summary>
/// <param name="writer"></param>
public void Display(StringWriter writer)
{
// Use it like this
ListNode<T> p = m_Head.Next;
writer.Write("The List Item is: ");
while (p != null)
{
writer.Write("{0}-->", p.Item);
p = p.Next;
}
writer.Write("NULL");
writer.Write(Environment.NewLine);
}
{
StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb);
this.Display (writer);
writer.Close ();
return sb.ToString();
}
public int IndexOf(T item)
{
Int32 index = 0;
this.Find(item, out index);
return index;
}
{
if (index < 0 || index >= this.m_Count)
throw new ArgumentOutOfRangeException("index", index, "Index value is out of range, please check!");
ListNode<T> node = new ListNode<T>(item);
while( index-- > 0 ) previousNode = previousNode.Next;
previousNode.Next = node;
m_Count++;
}
{
if (index < 0 || index >= this.m_Count)
throw new ArgumentOutOfRangeException("index", index, "Index value is out of range, please check!");
while (index-- > 0) previousNode = previousNode.Next;
if (node == null) return;
if (node == m_End) m_End = previousNode;
node.Next = null;
node = null;
}
{
if (index < 0 || index >= this.m_Count)
throw new ArgumentOutOfRangeException("index", index, "Index value is out of range, please check!");
while (index-- > 0) node = node.Next;
}
{
get { return this.GetNode(index).Item; }
set { this.GetNode(index).Item = value; }
}
}
}
{
internal class ListNode<T>
{
public T Item; // Element item
public ListNode<T> Next;
public ListNode(T value) : this() { this.Item = value; }
internal ListNode() { this.Next = null; }
}
public class LinkList<T> : ICollection<T>, IEnumerable<T>, IList<T>
{
private ListNode<T> m_Head;
private ListNode<T> m_End;
private Int32 m_Count;
EqualityComparer
<T> m_Comparer = EqualityComparer<T>.Default;#region ctor
public LinkList()
{
m_Head = new ListNode<T>();
m_End = m_Head;
}
public LinkList(T[] array)
: this()
{
if (array == null) throw new ArgumentNullException("array");
foreach (T item in array) this.Add(item);
}
#endregion
#region Utility methods
public bool IsEmpty { get { return m_Head.Next == null; } }
private ListNode<T> Find(T value, out Int32 index)
{
ListNode<T> node = m_Head.Next;
index = 0;
while (node != null && !m_Comparer.Equals(value, node.Item))
{
node = node.Next;
index++;
}
if (node == null) index = -1;
return node;
}
private ListNode<T> FindPrevious(T value)
{
ListNode<T> node = m_Head;
while (node.Next != null && !m_Comparer.Equals(value, node.Next.Item))
node = node.Next;
return node;
}
#endregion
#region ICollection<T> Members
public void Add(T item) // Add the item at end
{
ListNode<T> node = new ListNode<T>(item);
m_End.Next = node;
m_End = node;
m_Count++;
}
public void Clear()
{
ListNode<T> pos, temp;
pos = m_Head;
while (pos != null)
{
temp = pos.Next;
pos.Next = null;
pos = temp;
}
m_Count = 0;
m_End = m_Head;
}
public bool Contains(T item)
{
Int32 i = 0;
return this.Find(item, out i) != null;
}
public void CopyTo(T[] array, int index)
{
if (array == null)
throw new ArgumentNullException("array");
if ((index < 0) || (index >= array.Length))
throw new ArgumentOutOfRangeException("index", index, "Please check the index value!");
if ((array.Length - index) < this.Count)
throw new ArgumentException("Insufficient Space!");
ListNode
<T> node = m_Head.Next;while(node != null)
{
array[index++] = node.Item;
node = node.Next;
}
}
public int Count { get { return m_Count; } }
public bool IsReadOnly { get { return false; } }
public bool Remove(T item)
{
ListNode<T> preNode = this.FindPrevious(item);
ListNode<T> tempNode = null;
if (preNode.Next != null) // item is found
{
if (m_End == preNode.Next) m_End = preNode;
tempNode = preNode.Next; // node to be deleted
preNode.Next = tempNode.Next;
tempNode = null;
m_Count--;
return true;
}
return false;
}
#endregion
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
ListNode<T> node = this.m_Head.Next;
while(node != null)
{
yield return node.Item;
node = node.Next;
}
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
/// <summary>
/// StreamWriter = new StreamWriter(Console.OpenStandardOutput());
/// </summary>
/// <param name="writer"></param>
public void Display(StringWriter writer)
{
// Use it like this
ListNode<T> p = m_Head.Next;
writer.Write("The List Item is: ");
while (p != null)
{
writer.Write("{0}-->", p.Item);
p = p.Next;
}
writer.Write("NULL");
writer.Write(Environment.NewLine);
}
public override String ToString ()
{
StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb);
this.Display (writer);
writer.Close ();
return sb.ToString();
}
#region IList<T> Members
public int IndexOf(T item)
{
Int32 index = 0;
this.Find(item, out index);
return index;
}
public void Insert(int index, T item)
{
if (index < 0 || index >= this.m_Count)
throw new ArgumentOutOfRangeException("index", index, "Index value is out of range, please check!");
ListNode
<T> previousNode = this.m_Head.Next;ListNode<T> node = new ListNode<T>(item);
while( index-- > 0 ) previousNode = previousNode.Next;
node.Next
= previousNode.Next;previousNode.Next = node;
if (m_End.Next != null) m_End = node;
m_Count++;
}
public void RemoveAt(int index)
{
if (index < 0 || index >= this.m_Count)
throw new ArgumentOutOfRangeException("index", index, "Index value is out of range, please check!");
ListNode
<T> previousNode = this.m_Head;while (index-- > 0) previousNode = previousNode.Next;
ListNode
<T> node = previousNode.Next;if (node == null) return;
if (node == m_End) m_End = previousNode;
previousNode.Next
= node.Next;node.Next = null;
node = null;
m_Count
--;}
private ListNode<T> GetNode(int index)
{
if (index < 0 || index >= this.m_Count)
throw new ArgumentOutOfRangeException("index", index, "Index value is out of range, please check!");
ListNode
<T> node = this.m_Head.Next;while (index-- > 0) node = node.Next;
return node;
}
public T this[int index]
{
get { return this.GetNode(index).Item; }
set { this.GetNode(index).Item = value; }
}
#endregion
}
}
欢迎多提意见。