使用泛型LinkedList<T>类。下面的方法创建了一个LinkedList<T>类,并往链表对象中添加节点,然后使用了几种方法从链表节点中获得信息。
 
    public static void UseLinkedList()
    {
        // 创建一个LinkedList 对象.
        LinkedList<TodoItem> todoList = new LinkedList<TodoItem>();
        // 创建添加到链表内的TodoItem对象.
        TodoItem i1 = new TodoItem("paint door", "Should be done third");
        TodoItem i2 = new TodoItem("buy door", "Should be done first");
        TodoItem i3 = new TodoItem("assemble door", "Should be done second");
        TodoItem i4 = new TodoItem("hang door", "Should be done last");
        // 添加项目.
        todoList.AddFirst(i1);
        todoList.AddFirst(i2);
        todoList.AddBefore(todoList.Find(i1), i3);
        todoList.AddAfter(todoList.Find(i1), i4);
        // 显示所有项目.
        foreach (TodoItem tdi in todoList)
        {
            Console.WriteLine(tdi.Name + " : " + tdi.Comment);
        }
        // 显示链表内的第二个节点的信息
        Console.WriteLine("todoList.First.Next.Value.Name == " +
                            todoList.First.Next.Value.Name);
        // 显示链表内最后一个节点的前一节点信息.
        Console.WriteLine("todoList.Last.Previous.Value.Name == " +
                            todoList.Last.Previous.Value.Name);
}
 
这个方法的输出结果如下:
 
    buy door : Should be done first
    assemble door : Should be done second
    paint door : Should be done third
    hang door : Should be done last
    todoList.First.Value.Name == buy door
    todoList.First.Next.Value.Name == assemble door
    todoList.Last.Previous.Value.Name == paint door
 
下面是TodoItem类,它只简单地包含了两个字符串_name和_comment。
 
public class TodoItem
{
    public TodoItem(string name, string comment)
    {
        _name = name;
        _comment = comment;
    }
    private string _name = "";
    private string _comment = "";
    public string Name
    {
        get { return (_name); }
        set { _name = value; }
    }
    public string Comment
    {
        get { return (_comment); }
        set { _comment = value; }
    }
}
LinkedList<T>类在.NET framework中是一个双向链表。这是因为链表中的每一个节点都包含了前一节点和后一节点的指针。图4-1演示了这种结构,图中的每个node代表了一个单独的LinkedListNode<T>对象。
 
注意图中链表的每个节点(方块)包含了一个指向下一节点的指针(指向右边的箭头)和一个指向前一节点的指针(指向左边的箭头)。相反,单链表只包含指向下一节点的指针,它没有指向前一节点的指针。
 
在LinkedList类中,前一节点通过访问Previous属性获得,后一节点通过访问Next属性获得。链表中的第一个节点的Previous属性总是返回null值。两样,最后一个节点的Next属性也是返回null值。
 
链表中的每个节点(图4-1中用方块表示)实际上都是一个LinkedListNode<T>对象。所以LinkedList<T>对象实际上是由一组LinkedListNode<T>对象组成,所有这些LinkedListNode<T>对象都包含了访问下一个和前一个LinkedListNode<T>对象的属性。LinkedListNode<T>中所包含的对象可以通过Value属性访问。除了这些属性外,LinkedListNode<T>对象还有一个属性叫List,可以用它来访问所属的LinkedList<T>对象。
 
性能是我们非常关心的一个问题,List<T>类的性能优越于LinkedList<T>类。一般情况下在List<T>内添加和删除节点要比在LinkedList<T>内进行同样的操作快。对比List<T>.Add方法和LinkedList<T>类的Add*方法(译者注:之所以是Add*方法是因为LinkedList<T>中的添加方法有:AddAfter、AddBefore、AddFirst、AddLast),导到性能上的差异并非因为添加操作本身,而是LinkedList<T>在垃圾回收时的压力。List<T>的数据本质上是存放在托管堆中的一个大容量数组之上,然而LinkedList<T>有可能会把它的节点存放在托管堆的每个角落。这使得强制垃圾回收在处理托管堆中的LinkedList<T>节点对象时需要花费更多的力气。需要注意,List<T>.Insert方法可能会比LinkedList<T>中的任一个Add*方法要慢,但这取决于对象在List<T>的哪个位置插入。当在某个点插入一人新元素时,Insert方法必须移动它后面的所有元素一个位置。如果新元素插入到List<T>的尾部,移动元素所花费的开销比起垃圾回收所花费的开销就可以忽略不计了。
 
List<T>另外一个胜于LinkedList<T>的地方是可以使用索引访问。在List<T>中,您可以使用索引器并通过索引值来访问指定位置的某个元素。但在LinkedList<T>中就没有这么令人愉快了。在LinkedList<T>类中,您必须使用每个LinkedListNode<T>中的Previous和Next属性进行导航,并贯穿整个链表直到找到您所指定的位置。
 
在搜索一个元素或节点时,List<T>类也比LinkedList<T>类有速度上的优势。使用List<T>.BinarySearch方法在List<T>内查找元素比在LinkedList<T>类中使用相应的Contains、Find、FindLast方法更快,这是因为LinkedList<T>的方法执行线性搜索而List<T>.BinarySearch方法执行二分查找法。一般条件下,二分查找法利用元素在List<T>内是按顺序排列的。这使得在进行二分查找之前必须调用Sort方法(注意:当添加新元素时,Sort方法也会在BinarySearch方法之前被调用)。利用这些,二分查找将检查列表中的中间那个元素,并询问:你查找的对象是否大于列表中的当前对象?如果是这样,可知目标对象索引值将在当前对象之前。如果不是,则对象索引值在当前索引之后。二分查找算法保持询问,直到找到对象为止。恰恰相反,线性搜索从列表中的第一个元素开始查找指定元素,如果不是,则继续搜索下一个元素,直到在列表中找到相应的元素。

C#泛类型链表的实现的更多相关文章

  1. 将泛类型集合List类转换成DataTable

    /// <summary> /// 将泛类型集合List类转换成DataTable /// </summary> /// <param name="list&q ...

  2. [转]c# 泛类型(泛型) 以及强类型与弱类型的 理解及优化

    [泛型的概念](1)没有泛型的时候,所有的对象都是以object为基础,如果要使用时必须进行强制类型转换,如果对于值类型,则会导致不断拆箱装箱的过程,对系统消耗很大.(2)使用泛型时不需要通过obje ...

  3. java:警告:[unchecked] 对作为普通类型 java.util.HashMap 的成员的put(K,V) 的调用未经检查

    java:警告:[unchecked] 对作为普通类型 java.util.HashMap 的成员的put(K,V) 的调用未经检查 一.问题:学习HashMap时候,我做了这样一个程序: impor ...

  4. Objective-C路成魔【11-多态性、动态类型和动态绑定】

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 多态这个其 ...

  5. 【读书笔记】iOS-动态类型和动态绑定

    id是泛类型,可以用来存放各种类型的对象,使用id也就是使用“动态类型”. 动态类型,就是指,对象实际使用的是哪一个类是在执行期间确定的,而非在编译期间. 虽然id类型可以定义任何类型的对象,但是不要 ...

  6. Jedis操作笔记 redis的五种存储类型

    常用数据类型简介: redis常用五种数据类型:string,hash,list,set,zset(sorted set). 1.String类型 String是最简单的类型,一个key对应一个val ...

  7. Alan Cox:单向链表中prev指针的妙用

    之前发过一篇二级指针操作单向链表的例子,显示了C语言指针的灵活性,这次再探讨一个指针操作链表的例子,而且是一种完全不同的用法. 这个例子是linux-1.2.13网络协议栈里的,关于链表遍历& ...

  8. 【内核】内核链表使用说明,list.h注释

    list_entry定义 /** * list_entry - get the struct for this entry * @ptr: the &struct list_head poin ...

  9. Linux C 数据结构 ->单向链表<-(~千金散尽还复来~)

    之前看到一篇单向链表的博文,代码也看着很舒服,于是乎记录下来,留给自己~,循序渐进,慢慢 延伸到真正的内核链表~(敢问路在何方?路在脚下~) 1. 简介 链表是Linux 内核中最简单,最普通的数据结 ...

随机推荐

  1. Mac 下 Chrome 浏览器 快捷键

    ⌘-Option-I 打开“开发人员工具”. ⌘-Option-J 打开“JavaScript 控制台”. ⌘-Option-U 打开当前网页的源代码. 转自: http://www.harbin-s ...

  2. 用数据表创建树_delphi教程

    数据库结构:字段 类型ID 整型 索引(无重复)name 文本father 整型 //tree初始化procedure TForm1.FormActivate(Sender: TObject);var ...

  3. Java for LeetCode 036 Valid Sudoku

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

  4. hdu 1213 How Many Tables 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1213 有关系(直接或间接均可)的人就坐在一张桌子,我们要统计的是最少需要的桌子数. 并查集的入门题,什 ...

  5. NEFU 2016省赛演练一 B题(递推)

    HK Problem:B Time Limit:2000ms Memory Limit:65535K Description yy is interested in numbers and yy nu ...

  6. 菜菜买气球(codevs 2851)

    题目描述 Description 六一儿童节到了,菜菜爸爸带着菜菜来到了游乐园,菜菜可高兴坏了.这不,菜菜看到了一排卖气球的,便吵着闹着要买气球. 不过这些卖气球的也奇怪,他们都站成了一排,而且每个人 ...

  7. Linux设置IP

    进入 vi /etc/sysconfig/network-scripts/ifcfg-eth0  root # ifconfig eth0 192.168.22.232 root # route ad ...

  8. C++拷贝构造函数(深拷贝,浅拷贝)

    http://www.cnblogs.com/BlueTzar/articles/1223313.html 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a;  ...

  9. Java Hour 42 fastjson

    fastjson 神一样的存在,然后由于缺乏文档,很多功能完全不知道该怎么用. 42.1 字段的大小写问题 刚开始没想到会因为字段的大小写问题而导致反序列化json 失败. @Override pub ...

  10. strcat函数造成的段错误(Segmentation fault)

    转自:http://book.51cto.com/art/201311/419441.htm 3.21  strcat函数造成的段错误 代码示例 int main() { char dest[7]=& ...