首先,我们以“创建一个简单的、未实现泛型的、能包含任何类型的链表类”作为切入点;然后我们再对其改装成支持泛型的列表类。
我们都知道“链表”内部总是一个元素连接到下一个元素,所以我们需要创建一个类来表示其中的每一个节点。这个节点类,需要包含三个信息:1.之前的节点 2.本节点 3.之后的节点。
基于以上的分析,我们得到了节点类LinkedListNode:
View Code
public class LinkedListNode
{
public object Value { get; private set; }
public LinkedListNode(object value)
{
Value = value;
}
public object Prev { get; internal set; }
public object Next { get; internal set; }
}
class LinkedList:IEnumerable
{
public LinkedListNode First { get;private set; }
public LinkedListNode Last { get; private set; }
public LinkedListNode AddLast(object node)
{
LinkedListNode newNode = new LinkedListNode(node);
if (First == null)//如果链表为空
{
First = newNode;
Last = First;
}
else {
Last.Next = newNode;
Last = newNode;
}
return newNode;
}
public IEnumerator GetEnumerator()
{
LinkedListNode current = First;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
}
以下,我们对其添加新节点。可以看出几个问题:1.addLast(值类型)时,涉及到装箱过程(int->object) 2.没有类型安全:list1.AddLast(“6”); 3.foreach (int i in list1)中,涉及到拆箱过程(object -> int)
LinkedList list1 = new LinkedList();
list1.AddLast(2);
list1.AddLast(4);
list1.AddLast(“6”);
foreach (int i in list1)
{
Console.WriteLine(i);
}
现在我们对上诉两个类进行改装,使其成为支持泛型的类:
public class LinkedListNode<T>
{
public T Value { get; private set; }
public LinkedListNode(T value)
{
Value = value;
}
public T Prev { get; internal set; }
public T Next { get; internal set; }
}
class LinkedList<T> : IEnumerable<T>
{
public LinkedListNode<T> First { get;private set; }
public LinkedListNode<T> Last { get; private set; }
public LinkedListNode<T> AddLast(T node)
{
LinkedListNode<T> newNode = new LinkedListNode<T>(node);
if (First == null)//如果链表为空
{
First = newNode;
Last = First;
}
else {
Last.Next = newNode;
Last = newNode;
}
return newNode;
}
public IEnumerator<T> GetEnumerator()
{
LinkedListNode<T> current = First;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
}
LinkedList < int > list2 = new LinkedList < int > ();
list2.AddLast(1);
list2.AddLast(3);
list2.AddLast(5);
foreach (int i in list2)
{
Console.WriteLine(i);
}
现在使用以上代码,将不会有装箱、拆箱过程中的性能损失。同时还是类型安全的,如果foreach (int i in list2)中声明的不是int,那么编译期间就会报错。