算法学习,单链表 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
}
}
欢迎多提意见。
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
}
}
欢迎多提意见。
相关文章推荐
- 经典算法学习——链表实现冒泡排序
- 学习C#从俄罗斯方块开始(二)俄罗斯方块的规则和算法的简单实现
- 算法学习 - 链表的游标实现~ C++
- 数据结构与算法学习笔记——链表部分实现(数组形式)
- 二元查找树转变成排序的双向链表之C#算法实现
- C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法
- 无聊用C#2.0泛型实现的链表(C#数据结构一)
- 算法学习 - 栈的链表实现(C++)
- 转:C#数据结构和算法学习系列十三----链表
- 算法学习第二课链表C语言实现
- C#中的泛型链表的实现
- 算法研究学习一(用C和C#实现)
- C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法
- Java学习笔记——链表的泛型实现和序列化读写
- c#打包文件解压缩 C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法 一个简单例子理解C#的协变和逆变 对于过长字符串的大小比对
- 学习C#从俄罗斯方块开始(二)俄罗斯方块的规则和算法的简单实现
- C# 泛型实现链表、代码重用
- C# 简单链表的实现下(使用泛型)
- C#学习之利用泛型实现列表功能
- 算法(第四版)学习笔记之java实现栈和队列(链表实现)