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个元素,每个元素分别是引用每个优先级的最后一个文档对象。
  

  

      public class PriorityDocumentManager
{
private readonly LinkedList<Document> documentList; // priorities 0.9
private readonly List<LinkedListNode<Document>> priorityNodes; public PriorityDocumentManager()
{
documentList = new LinkedList<Document>(); priorityNodes = new List<LinkedListNode<Document>>();
for (int i = ; i < ; i++)
{
priorityNodes.Add(new LinkedListNode<Document>(null));
}
} public void AddDocument(Document d)
{
//Contract.Requires<ArgumentNullException>(d != null, "argument d must not be null");
if (d == null) throw new ArgumentNullException("d"); AddDocumentToPriorityNode(d, d.Priority);
} private void AddDocumentToPriorityNode(Document doc, int priority)
{
if (priority > || priority < )
throw new ArgumentException("Priority must be between 0 and 9"); //检查优先级列表priorityNodes中是否有priority这个优先级
if (priorityNodes[priority].Value == null)
{
//如果没有,递减优先级值,递归AddDocumentToPriorityNode方法,检查是否有低一级的优先级
--priority;
if (priority >= )
{
AddDocumentToPriorityNode(doc, priority);
}
else //如果已经没有更低的优先级时,就直接在链表中添加该节点,并将这个节点添加到优先级列表
{
documentList.AddLast(doc);
priorityNodes[doc.Priority] = documentList.Last;
}
return;
}
else //优先级列表priorityNodes中有priority这个优先级
{
LinkedListNode<Document> prioNode = priorityNodes[priority];
//区分优先级列表priorityNodes存在这个指定的优先级值的节点,还是存在较低的优先级值的节点
if (priority == doc.Priority)
// 如果存在这个指定的优先级值的节点
{
//将这个节点添加到链表
documentList.AddAfter(prioNode, doc); // 将这个节点赋予优先级列表中的这个优先级值的节点,因为优先级节点总是引用指定优先级节点的最后一个文档
priorityNodes[doc.Priority] = prioNode.Next;
}
else //如果存在较低的优先级值的节点
{
//在链表中找到这个较低优先级的第一个节点,把要添加的节点放到它前面
LinkedListNode<Document> firstPrioNode = prioNode;
//通过循环,使用Previous找到这个优先级的第一个节点
while (firstPrioNode.Previous != null &&
firstPrioNode.Previous.Value.Priority == prioNode.Value.Priority)
{
firstPrioNode = prioNode.Previous;
prioNode = firstPrioNode;
} documentList.AddBefore(firstPrioNode, doc); // 设置一个新的优先级节点
priorityNodes[doc.Priority] = firstPrioNode.Previous;
}
}
} public void DisplayAllNodes()
{
foreach (Document doc in documentList)
{
Console.WriteLine("priority: {0}, title {1}", doc.Priority, doc.Title);
}
} // returns the document with the highest priority
// (that's first in the linked list)
public Document GetDocument()
{
Document doc = documentList.First.Value;
documentList.RemoveFirst();
return doc;
} } //存储在链表中的元素是Document类型
public class Document
{
public string Title { get; private set; }
public string Content { get; private set; }
public byte Priority { get; private set; } public Document(string title, string content, byte priority)
{
this.Title = title;
this.Content = content;
this.Priority = priority;
}
}

客户端代码:
  

static void Main()
{
PriorityDocumentManager pdm = new PriorityDocumentManager();
pdm.AddDocument(new Document("one", "Sample", ));
pdm.AddDocument(new Document("two", "Sample", ));
pdm.AddDocument(new Document("three", "Sample", ));
pdm.AddDocument(new Document("four", "Sample", ));
pdm.AddDocument(new Document("five", "Sample", ));
pdm.AddDocument(new Document("six", "Sample", ));
pdm.AddDocument(new Document("seven", "Sample", ));
pdm.AddDocument(new Document("eight", "Sample", )); pdm.DisplayAllNodes(); Console.ReadKey(); }

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. Android自学反思总结(上)

    从接触Android到现在有几个月的时间了,基本全部都是靠自学,从大一上学期学习完c语言,接着利用寒假时间和开学一个月左右的时间自学完javase,接着在导员的督促下,开始了Android学习之旅,现 ...

  2. Git远程仓库(二)

    昨天讲了Git安装使用和基本的命令,今天我说一下如何通过Git将本地管理的仓库添加到远程库 首先我们需要在www.github.com(如果打不开网页,请注意科学上网)上注册一个免费的账号,邮箱验证完 ...

  3. JavaScript实现

    JavaScript实现 Javascript实现虽然JavaScript和ECMAScript通常都被人们用来表达相同的含义,但JavaScript的含义却比ECMA-262中规定的要多得多.没错, ...

  4. iOS开发之Xib和storyboard对比

    相同点: (2)都用来描述软件界面 (2)都用Interface Builder工具来编辑 不同点: (1)Xib是轻量级的,用来描述局部的UI界面 (2)Storyboard是重量级的,用来描述整个 ...

  5. 小程序新能力-个人开发者尝鲜微信小程序

    个人开发者的福利 微信小程序,刚听到这个新名词的时候,我就兴冲冲的去找入口,看看自己能不能搞个微信小程序的HelloWorld,毕竟能在微信上把自己写的一些小工具跑起来还是满炫酷的. 没想,网上一查, ...

  6. OC--Runtime知识点整理

    1.Runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译 ...

  7. 随机跳转页面之使用VBA公共变量

    p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...

  8. mysql5.7.1.3 安装说明 和出现的问题

    1.可以去官网下载 http://dev.mysql.com/downloads/mysql/ 链接: http://pan.baidu.com/s/1hsO5OX2 密码: jmc6 2.解压到文件 ...

  9. js按值传递和按引用传递

    摘要:js的数据类型有种划分方式为 原始数据类型和 引用数据类型. 原始数据类型 存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置.栈区包括了 变量的标识符和变量的值. ...

  10. 将1、2、3、……、n这n个连续自然数分成g组,使每组的和相等。g组中个数最多的一组有几个?

    <style type="text/css"> #content { width: 600px; margin: 150px auto 0 auto; } dl dd ...