LinkedList<T>是一个双向链表,其元素会指向它前面和后面的元素。这样,通过移动到下一个元素可以正向遍历链表,通过移动到前一个元素可以反向遍历链表。
  
  链表在存储元素时,不仅要存储元素的值,还必须存储每个元素的下一个元素和上一个元素的信息。这就是LinkedList<T>包含LinkedListNode<T>类型的元素的原因。使用LinkedListNode<T>,可以获得列表中的下一个和上一个元素。LinkedListNode<T>定义了属性List,Next,Previous和Value。List属性返回与节点相关的LinkedList<T>对象。Next和Previous属性用于遍历链表,访问当前节点之后和之前的节点。Value属性返回与节点相关的元素,其类型是T。
  链表的优点是,如果将元素插入到列表的中间位置,使用链表就会很快。在插入一个元素时,秩序啊哟修改上一个元素的Next引用和下一个元素的Previous引用,使它们引用所插入的元素。在  List<T>(http://www.cnblogs.com/afei-24/p/6824791.html)中,插入一个元素,需要移动该元素后面的所以元素。
  链表的缺点是,链表元素只能一个接一个的访问,这需要较长时间来查找位于链表中间或尾部的元素。

  LinkedList<T>类定义的成员可以访问链表中的第一个和最后一个元素(First和Last);
  在指定位置插入元素:AddAfter(),AddFirst()和AddLast();
  删除指定位置的元素:Remove(),RemoveFirst(),RemoveLast();
  搜索:Find(),FindLast()。

  下面用一个例子演示链表。在链表中,文档按照优先级来排序。如果多个文档的优先级相同,这些元素就按照文档的插入时间来排序:
  PriorityDocumentManager类使用一个链表LinkedList<Document> documentList和一个列表List<LinkedListNode<Document>> priorityNodes,链表包含Document对象,Document对象包含文档的标题和优先级。列表List<LinkedListNode<Document>> priorityNodes应最多包含10个元素,每个元素分别是引用每个优先级的最后一个文档对象。
  

  

  1.       public class PriorityDocumentManager
  2. {
  3. private readonly LinkedList<Document> documentList;
  4.  
  5. // priorities 0.9
  6. private readonly List<LinkedListNode<Document>> priorityNodes;
  7.  
  8. public PriorityDocumentManager()
  9. {
  10. documentList = new LinkedList<Document>();
  11.  
  12. priorityNodes = new List<LinkedListNode<Document>>();
  13. for (int i = ; i < ; i++)
  14. {
  15. priorityNodes.Add(new LinkedListNode<Document>(null));
  16. }
  17. }
  18.  
  19. public void AddDocument(Document d)
  20. {
  21. //Contract.Requires<ArgumentNullException>(d != null, "argument d must not be null");
  22. if (d == null) throw new ArgumentNullException("d");
  23.  
  24. AddDocumentToPriorityNode(d, d.Priority);
  25. }
  26.  
  27. private void AddDocumentToPriorityNode(Document doc, int priority)
  28. {
  29. if (priority > || priority < )
  30. throw new ArgumentException("Priority must be between 0 and 9");
  31.  
  32. //检查优先级列表priorityNodes中是否有priority这个优先级
  33. if (priorityNodes[priority].Value == null)
  34. {
  35. //如果没有,递减优先级值,递归AddDocumentToPriorityNode方法,检查是否有低一级的优先级
  36. --priority;
  37. if (priority >= )
  38. {
  39. AddDocumentToPriorityNode(doc, priority);
  40. }
  41. else //如果已经没有更低的优先级时,就直接在链表中添加该节点,并将这个节点添加到优先级列表
  42. {
  43. documentList.AddLast(doc);
  44. priorityNodes[doc.Priority] = documentList.Last;
  45. }
  46. return;
  47. }
  48. else //优先级列表priorityNodes中有priority这个优先级
  49. {
  50. LinkedListNode<Document> prioNode = priorityNodes[priority];
  51. //区分优先级列表priorityNodes存在这个指定的优先级值的节点,还是存在较低的优先级值的节点
  52. if (priority == doc.Priority)
  53. // 如果存在这个指定的优先级值的节点
  54. {
  55. //将这个节点添加到链表
  56. documentList.AddAfter(prioNode, doc);
  57.  
  58. // 将这个节点赋予优先级列表中的这个优先级值的节点,因为优先级节点总是引用指定优先级节点的最后一个文档
  59. priorityNodes[doc.Priority] = prioNode.Next;
  60. }
  61. else //如果存在较低的优先级值的节点
  62. {
  63. //在链表中找到这个较低优先级的第一个节点,把要添加的节点放到它前面
  64. LinkedListNode<Document> firstPrioNode = prioNode;
  65. //通过循环,使用Previous找到这个优先级的第一个节点
  66. while (firstPrioNode.Previous != null &&
  67. firstPrioNode.Previous.Value.Priority == prioNode.Value.Priority)
  68. {
  69. firstPrioNode = prioNode.Previous;
  70. prioNode = firstPrioNode;
  71. }
  72.  
  73. documentList.AddBefore(firstPrioNode, doc);
  74.  
  75. // 设置一个新的优先级节点
  76. priorityNodes[doc.Priority] = firstPrioNode.Previous;
  77. }
  78. }
  79. }
  80.  
  81. public void DisplayAllNodes()
  82. {
  83. foreach (Document doc in documentList)
  84. {
  85. Console.WriteLine("priority: {0}, title {1}", doc.Priority, doc.Title);
  86. }
  87. }
  88.  
  89. // returns the document with the highest priority
  90. // (that's first in the linked list)
  91. public Document GetDocument()
  92. {
  93. Document doc = documentList.First.Value;
  94. documentList.RemoveFirst();
  95. return doc;
  96. }
  97.  
  98. }
  99.  
  100. //存储在链表中的元素是Document类型
  101. public class Document
  102. {
  103. public string Title { get; private set; }
  104. public string Content { get; private set; }
  105. public byte Priority { get; private set; }
  106.  
  107. public Document(string title, string content, byte priority)
  108. {
  109. this.Title = title;
  110. this.Content = content;
  111. this.Priority = priority;
  112. }
  113. }

客户端代码:
  

  1. static void Main()
  2. {
  3. PriorityDocumentManager pdm = new PriorityDocumentManager();
  4. pdm.AddDocument(new Document("one", "Sample", ));
  5. pdm.AddDocument(new Document("two", "Sample", ));
  6. pdm.AddDocument(new Document("three", "Sample", ));
  7. pdm.AddDocument(new Document("four", "Sample", ));
  8. pdm.AddDocument(new Document("five", "Sample", ));
  9. pdm.AddDocument(new Document("six", "Sample", ));
  10. pdm.AddDocument(new Document("seven", "Sample", ));
  11. pdm.AddDocument(new Document("eight", "Sample", ));
  12.  
  13. pdm.DisplayAllNodes();
  14.  
  15. Console.ReadKey();
  16.  
  17. }

C#集合之链表的更多相关文章

  1. 对象数组、集合、链表(java基础知识十五)

    1.对象数组的概述和使用 * 需求:我有5个学生,请把这个5个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息. Student[] arr = new Student[5]; //存储学生 ...

  2. C#泛型集合之——链表

    链表基础 1.概述:C#中泛型集合中的链表—LinkedList 是一个双向链表,其结点为LinkedListNode 结构 其中,结点结构包含:Next,Previous,Value三部分.且结点中 ...

  3. Java 集合系列01之 总体框架

      Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.*Java集合主要可以划分为4个部分:List列表.Set ...

  4. Java集合系列:-----------01集合的整体框架

    内容来自:http://www.cnblogs.com/skywang12345/p/3308498.html Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映 ...

  5. Java 集合系列 01 总体框架

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  6. java核心技术记录之集合

    java库中的具体集合: 集合类型 描述 ArrayList 一种可以动态增长和缩减的索引序列 LinkedList 一种可以在任何位置进行高效地插入和删除操作的有序序列 ArrarDeque 一种用 ...

  7. 不相交集合ADT

    不相交集合数据结构保持一组不相交的动态集合S={S1,S2,...,SK},每个集合通过一个代表来识别,代表即集合中的某个成员. 如果x表示一个对象,不相交集合支持以下操作: MAKE-SET(x): ...

  8. java集合系列——java集合概述(一)

    在JDK中集合是很重要的,学习java那么一定要好好的去了解一下集合的源码以及一些集合实现的思想! 一:集合的UML类图(网上下载的图片) Java集合工具包位置是java.util.* 二:集合工具 ...

  9. Java集合之Collection

    Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.* Java集合主要可以划分为4个部分:List列表.Set集 ...

随机推荐

  1. 【SF】开源的.NET CORE 基础管理系统 - 安装篇

    [SF]开源的.NET CORE 基础管理系统 -系列导航 1.开发必备工具 IDE:VS2017 运行环境:netcoreapp1.1 数据库:SQL Server 2012+ 2.获取最新源代码 ...

  2. cuda编程学习5——波纹ripple

    /共有DIM×DIM个像素,每个像素对应一个线程dim3 blocks(DIM/16,DIM/16);//2维dim3 threads(16,16);//2维kernel<<<blo ...

  3. Android开发之AsyncTask示例Demo

    今天做了一个AsyncTask的小Demo,内含注释,通过此Demo,可以对AsyncTask有一个详细的了解 已经将项目上传到了GitHub上(程序有一个小bug,在第一次提交有说明,有解决方法请留 ...

  4. 2015.07.12hadoop伪分布安装

    hadoop伪分布安装   Hadoop2的伪分布安装步骤[使用root用户用户登陆]other进去超级用户拥有最高的权限 1.1(桥接模式)设置静态IP ,,修改配置文件,虚拟机IP192.168. ...

  5. 将基因组数据分类并写出文件,python,awk,R data.table速度PK

    由于基因组数据过大,想进一步用R语言处理担心系统内存不够,因此想着将文件按染色体拆分,发现python,awk,R 语言都能够非常简单快捷的实现,那么速度是否有差距呢,因此在跑几个50G的大文件之前, ...

  6. go单元测试进阶篇

    作者介绍:熊训德(英文名:Sundy),16年毕业于四川大学大学并加入腾讯.目前在腾讯云从事hadoop生态相关的云存储和计算等后台开发,喜欢并专注于研究大数据.虚拟化和人工智能等相关技术. 本文档说 ...

  7. [SinGuLaRiTy] 2017-03-27 综合性测试

    [SinGuLaRiTy-1013] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 这是 三道 USACO 的题...... 第一题:奶牛飞 ...

  8. WPF之路一:相对路径图片显示

    由于公司项目的需要,改为WPF开发,因此需要学习WPF,遇到的第一个问题就是在显示的图片的时候,写绝对路径,图片显示没有问题,但是写相对路径的时候,发现图片无法正常显示,在网上搜了一下,得到的答案是需 ...

  9. 使用Jersey实现图片服务器与应用服务器分离

         现在模拟一下Jersey从客户端发送图片到服务器.   1.Tomcat准备 (1)解压一个新的Tomcat作为图片服务器,然后修改端口号(有3处).                (2)然 ...

  10. jQuery基础学习(一)—jQuery初识

    一.jQuery概述 1.jQuery的优点      jQuery是一个优秀的JavaScript库,极大地简化了遍历HTML文档.操作DOM.处理事件.执行动画和开发Ajax的操作.它有以下几点优 ...