您的位置:首页 > 编程语言 > C#

算法学习,单链表 C# 泛型实现

2007-10-18 20:44 666 查看
这个链表没有暴露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;

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

欢迎多提意见。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: