C#集合之链表
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#集合之链表的更多相关文章
- 对象数组、集合、链表(java基础知识十五)
1.对象数组的概述和使用 * 需求:我有5个学生,请把这个5个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息. Student[] arr = new Student[5]; //存储学生 ...
- C#泛型集合之——链表
链表基础 1.概述:C#中泛型集合中的链表—LinkedList 是一个双向链表,其结点为LinkedListNode 结构 其中,结点结构包含:Next,Previous,Value三部分.且结点中 ...
- Java 集合系列01之 总体框架
Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.*Java集合主要可以划分为4个部分:List列表.Set ...
- Java集合系列:-----------01集合的整体框架
内容来自:http://www.cnblogs.com/skywang12345/p/3308498.html Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映 ...
- Java 集合系列 01 总体框架
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- java核心技术记录之集合
java库中的具体集合: 集合类型 描述 ArrayList 一种可以动态增长和缩减的索引序列 LinkedList 一种可以在任何位置进行高效地插入和删除操作的有序序列 ArrarDeque 一种用 ...
- 不相交集合ADT
不相交集合数据结构保持一组不相交的动态集合S={S1,S2,...,SK},每个集合通过一个代表来识别,代表即集合中的某个成员. 如果x表示一个对象,不相交集合支持以下操作: MAKE-SET(x): ...
- java集合系列——java集合概述(一)
在JDK中集合是很重要的,学习java那么一定要好好的去了解一下集合的源码以及一些集合实现的思想! 一:集合的UML类图(网上下载的图片) Java集合工具包位置是java.util.* 二:集合工具 ...
- Java集合之Collection
Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.* Java集合主要可以划分为4个部分:List列表.Set集 ...
随机推荐
- 【SF】开源的.NET CORE 基础管理系统 - 安装篇
[SF]开源的.NET CORE 基础管理系统 -系列导航 1.开发必备工具 IDE:VS2017 运行环境:netcoreapp1.1 数据库:SQL Server 2012+ 2.获取最新源代码 ...
- cuda编程学习5——波纹ripple
/共有DIM×DIM个像素,每个像素对应一个线程dim3 blocks(DIM/16,DIM/16);//2维dim3 threads(16,16);//2维kernel<<<blo ...
- Android开发之AsyncTask示例Demo
今天做了一个AsyncTask的小Demo,内含注释,通过此Demo,可以对AsyncTask有一个详细的了解 已经将项目上传到了GitHub上(程序有一个小bug,在第一次提交有说明,有解决方法请留 ...
- 2015.07.12hadoop伪分布安装
hadoop伪分布安装 Hadoop2的伪分布安装步骤[使用root用户用户登陆]other进去超级用户拥有最高的权限 1.1(桥接模式)设置静态IP ,,修改配置文件,虚拟机IP192.168. ...
- 将基因组数据分类并写出文件,python,awk,R data.table速度PK
由于基因组数据过大,想进一步用R语言处理担心系统内存不够,因此想着将文件按染色体拆分,发现python,awk,R 语言都能够非常简单快捷的实现,那么速度是否有差距呢,因此在跑几个50G的大文件之前, ...
- go单元测试进阶篇
作者介绍:熊训德(英文名:Sundy),16年毕业于四川大学大学并加入腾讯.目前在腾讯云从事hadoop生态相关的云存储和计算等后台开发,喜欢并专注于研究大数据.虚拟化和人工智能等相关技术. 本文档说 ...
- [SinGuLaRiTy] 2017-03-27 综合性测试
[SinGuLaRiTy-1013] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 这是 三道 USACO 的题...... 第一题:奶牛飞 ...
- WPF之路一:相对路径图片显示
由于公司项目的需要,改为WPF开发,因此需要学习WPF,遇到的第一个问题就是在显示的图片的时候,写绝对路径,图片显示没有问题,但是写相对路径的时候,发现图片无法正常显示,在网上搜了一下,得到的答案是需 ...
- 使用Jersey实现图片服务器与应用服务器分离
现在模拟一下Jersey从客户端发送图片到服务器. 1.Tomcat准备 (1)解压一个新的Tomcat作为图片服务器,然后修改端口号(有3处). (2)然 ...
- jQuery基础学习(一)—jQuery初识
一.jQuery概述 1.jQuery的优点 jQuery是一个优秀的JavaScript库,极大地简化了遍历HTML文档.操作DOM.处理事件.执行动画和开发Ajax的操作.它有以下几点优 ...