//using System;
//using System.Collections.Generic;
//using System.Text;
//using System.Collections;
//public class LinkedListNode
//{
// public LinkedListNode(Object value)
// {
// this.value = value;
// }
// //结点数据值
// private object value;
// public object Value
// {
// get
// {
// return this.value;
// }
// }
// //双向结点指向引用
// private LinkedListNode next;
// private LinkedListNode pre;
// public LinkedListNode Next
// {
// get { return this.next; }
// internal set { this.next = value; }
// }
// public LinkedListNode Pre
// {
// get { return this.pre; }
// internal set { this.pre = value; }
// }
//}
结点的数据存储在Object类型的Value字段中。下面我们来创建链表类,该链表类有一个头结点、尾结点和在链表的末尾添加/删除结点的方法:
双向链表类
//public class LinkedList
//{
// //头结点
// private LinkedListNode head;
// public LinkedListNode Head
// {
// get { return this.head; }
// }
// //尾结点
// private LinkedListNode last;
// public LinkedListNode Last
// {
// get { return this.last; }
// }
// //在链表尾插入结点
// public LinkedListNode AddNode(Object value)
// {
// LinkedListNode node = new LinkedListNode(value);
// if (head == null)
// {
// head = node;
// last = head;
// }
// else
// {
// last.Next = node;
// node.Pre = last;
// last = node;
// }
// return last;
// }
// //在链表尾删除结点
// public LinkedListNode SubNode()
// {
// if (last == null)
// {
// return null;
// }
// else
// {
// LinkedListNode node = last.Pre;
// node.Next = null;
// last = node;
// }
// return last;
// }
//}
因为是链表,所以我们希望能使用foreach遍历链表,那么,将链表类LinkedList继承IEnumerable接口并实现GetEnumerator()方法:
//using System;
//using System.Collections.Generic;
using System.;
//using System.Text;
//using System.Collections;
//namespace ConsoleApplication1
//{
// //结点类
// public class LinkedListNode
// {
// public LinkedListNode(Object value)
// {
// this.value = value;
// }
// //结点数据值
// private object value;
// public object Value
// {
// get
// {
// return this.value;
// }
// }
// //双向结点指向引用
// private LinkedListNode next;
// private LinkedListNode pre;
// public LinkedListNode Next
// {
// get { return this.next; }
// internal set { this.next = value; }
// }
// public LinkedListNode Pre
// {
// get { return this.pre; }
// internal set { this.pre = value; }
// }
// }
// //双向链表类
// public class LinkedList : IEnumerable
// {
// //头结点
// private LinkedListNode head;
// public LinkedListNode Head
// {
// get { return this.head; }
// }
// //尾结点
// private LinkedListNode last;
// public LinkedListNode Last
// {
// get { return this.last; }
// }
// //在链表尾插入结点
// public LinkedListNode AddNode(Object value)
// {
// LinkedListNode node = new LinkedListNode(value);
// if (head == null)
// {
// head = node;
// last = head;
// }
// else
// {
// last.Next = node;
// node.Pre = last;
// last = node;
// }
// return last;
// }
// //在链表尾删除结点
// public LinkedListNode SubNode()
// {
// if (last == null)
// {
// return null;
// }
// else
// {
// LinkedListNode node = last.Pre;
// node.Next = null;
// last = node;
// }
// return last;
// }
// #region IEnumerable 成员
// public IEnumerator GetEnumerator()
// {
// LinkedListNode curr = head;
// while (curr != null)
// {
// yield return curr.Value;
// curr = curr.Next;
// }
// }
// #endregion
// }
//}
//这样我们就可以使用链表了,但该链表中的存储数据只能使Object类型的,这就并不能保证链表中的数据是类型统一的,因此在使用foreach遍历链表时可能出现致命的错误。比如该链表中有整形数据和字符串数据。而且,该链表并不能够为我们提供一个标准的模板。
//下面,我们改进LinkedListNode结点类,使其使用泛型——存储数据的类型使我们任意指定的类型:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace LinkedListNode
{
public class LinkedListNode<T>
{
public LinkedListNode(T value)
{
this.value = value;
}
//结点数据值
private T value;
public T Value
{
get
{
return this.value;
}
}
//双向结点指向引用
private LinkedListNode<T> next;
private LinkedListNode<T> pre;
public LinkedListNode<T> Next
{
get { return this.next; }
internal set { this.next = value; }
}
public LinkedListNode<T> Pre
{
get { return this.pre; }
internal set { this.pre = value; }
}
}
//同样,也需要将链表类改为泛型类:
public class LinkedList<T> : IEnumerable<T>
{
//头结点
private LinkedListNode<T> head;
public LinkedListNode<T> Head
{
get { return this.head; }
}
//尾结点
private LinkedListNode<T> last;
public LinkedListNode<T> Last
{
get { return this.last; }
}
//在链表尾插入结点
public LinkedListNode<T> AddNode(T value)
{
LinkedListNode<T> node = new LinkedListNode<T>(value);
if (head == null)
{
head = node;
last = head;
}
else
{
last.Next = node;
node.Pre = last;
last = node;
}
return last;
}
//在链表尾删除结点
public LinkedListNode<T> SubNode()
{
if (last == null)
{
return null;
}
else
{
LinkedListNode<T> node = last.Pre;
node.Next = null;
last = node;
}
return last;
}
#region IEnumerable 成员
public IEnumerator<T> GetEnumerator()
{
LinkedListNode<T> curr = head;
while (curr != null)
{
yield return curr.Value;
curr = curr.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
class Program
{
static void Main(string[] args)
{
LinkedList<int> list2 = new LinkedList<int>();
list2.AddNode(1);
list2.AddNode(3);
list2.AddNode(5);
Console.WriteLine("Before Sub:");
foreach (int i in list2)
{
Console.WriteLine(i);
}
Console.WriteLine("After Sub:");
list2.SubNode();
foreach (int i in list2)
{
Console.WriteLine(i);
}
Console.ReadLine();
}
}
}
//这样我们就保证了链表中数据的统一性,因此可以安全的使用foreach遍历链表了。
//其实,我个人认为,泛型也就是我们在编写代码时并不知道要使用的数据类型是什么,而是在使用代码时规定数据类型的,这样,我们就很容易的创建复用的模板代码,即减少了代码编写的工作,也节省了空间资源。