iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#集合之链表的用法
  • 537
分享到

C#集合之链表的用法

2024-04-02 19:04:59 537人浏览 独家记忆
摘要

LinkedList<T>是一个双向链表,其元素会指向它前面和后面的元素。这样,通过移动到下一个元素可以正向遍历链表,通过移动到前一个元素可以反向遍历链表。 链表在存储

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>(https://www.jb51.net/article/244084.htm)中,插入一个元素,需要移动该元素后面的所以元素。
链表的缺点是,链表元素只能一个接一个的访问,这需要较长时间来查找位于链表中间或尾部的元素。
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>>(10);
              for (int i = 0; i < 10; 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 > 9 || priority < 0)
                        throw new ArgumentException("Priority must be between 0 and 9");

              //检查优先级列表priorityNodes中是否有priority这个优先级
              if (priorityNodes[priority].Value == null)
              {
                //如果没有,递减优先级值,递归AddDocumentToPriorityNode方法,检查是否有低一级的优先级
                --priority;
                if (priority >= 0)
                {
                  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", 8));
          pdm.AddDocument(new Document("two", "Sample", 3));
          pdm.AddDocument(new Document("three", "Sample", 4));
          pdm.AddDocument(new Document("four", "Sample", 8));
          pdm.AddDocument(new Document("five", "Sample", 1));
          pdm.AddDocument(new Document("six", "Sample", 9));
          pdm.AddDocument(new Document("seven", "Sample", 1));
          pdm.AddDocument(new Document("eight", "Sample", 1));

          pdm.DisplayAllNodes();

          Console.ReadKey();

        }

到此这篇关于C#集合之链表的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: C#集合之链表的用法

本文链接: https://www.lsjlt.com/news/145667.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#集合之链表的用法
    LinkedList<T>是一个双向链表,其元素会指向它前面和后面的元素。这样,通过移动到下一个元素可以正向遍历链表,通过移动到前一个元素可以反向遍历链表。 链表在存储...
    99+
    2024-04-02
  • C#集合之列表的用法
    目录1.创建列表2.添加元素3.插入元素4.访问元素5.删除元素6.搜索7.排序8.类型转换9.只读集合.NET Framework为动态列表List提供泛型类List<T&g...
    99+
    2024-04-02
  • C#集合的链表怎么用
    这篇文章主要介绍了C#集合的链表怎么用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#集合的链表怎么用文章都会有所收获,下面我们一起来看看吧。LinkedList<T>是一个双向链表,其元素会指向...
    99+
    2023-06-30
  • C#集合之有序列表的用法
    如果需要基于键对所需集合排序,就可以使用SortedList<TKey,TValue>类。这个类按照键给元素排序。这个集合中的值和键都可以使用任何类型。定义为键的自定义类...
    99+
    2024-04-02
  • C#集合之并发集合的用法
    .NET 4 开始,在System.Collection.Concurrent中提供了几个线程安全的集合类。线程安全的集合可防止多个线程以相互冲突的方式访问集合。为了对集合进行线程安...
    99+
    2024-04-02
  • C#集合之集(set)的用法
    包含不重复元素的集合称为“集(set)”。.NET Framework包含两个集HashSet<T>和SortedSet<T>,它们都...
    99+
    2024-04-02
  • C#集合之不变集合的用法
    如果对象可以改变其状态,就很难在多个同时运行的任务中使用。这些集合必须同步。如果对象不能改变器状态,就很容易在多个线程中使用。Microsoft提供了一个新的集合库:Microsof...
    99+
    2024-04-02
  • C#集合之可观察集合的用法
    如果需要集合中的元素何时删除或添加的信息,可以使用ObservableCollection<T>类。这个类是为WPF定义的,这样UI就可以得知集合的变化。这个类在程序集W...
    99+
    2024-04-02
  • C#集合之栈的用法
    栈(Stack)和队列是非常类似的一个容器,只是栈是一个后进先出(LIFO)的容器。栈用Push()方法在栈中添加元素,用Pop()方法获取最近添加的一个元素: Stack<...
    99+
    2024-04-02
  • C#集合之队列的用法
    队列是其元素按照先进先出(FIFO)的方式来处理的集合。队列使用System.Collections.Generic名称空间中的泛型类Queue<T>实现。在内部,Que...
    99+
    2024-04-02
  • C#集合之字典的用法
    字典表示一种复杂的数据结构,这种数据结构允许按照某个键来访问元素。字典也称为映射或散列表。字典的主要特性是能根据键快速查找值。也可以自由添加和删除元素,这有点像List<T&g...
    99+
    2024-04-02
  • C#集合之位数组的用法
    如果需要处理的数字有许多位,就可以使用BitArray类和BitVector32结构。BitArray类位于System.Collection,BitVector32结构位于Syst...
    99+
    2024-04-02
  • C#集合之有序列表怎么用
    本文小编为大家详细介绍“C#集合之有序列表怎么用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C#集合之有序列表怎么用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。如果需要基于键对所需集合排序,就可以使用Sor...
    99+
    2023-06-30
  • C#集合之自定义集合类
    一、非泛型方式,继承自CollectionBase public class MyClass { public static void Main() { ...
    99+
    2024-04-02
  • C语言深入探索之单链表与typedef的用法
    目录前言详解typedef关键字含义具体使用详解单链表参数形式指针知识补充单链表形参详解单链表实战案例完整代码实现详解头插建表运行效果前言 昨天博主去本站问答贴子逛了逛,然后发现了好...
    99+
    2024-04-02
  • C/C++合并两个升序链表的方式
    目录合并两个升序链表算法的思想代码实现+注释合并K个升序链表(递归方法)归并的思想先来看合并两个有序链表的代码我们再来看合并K个链表的递归方法合并两个升序链表 算法的思想 1.需要合...
    99+
    2024-04-02
  • C语言结构体使用之链表
    目录一、结构体的概念二、结构体的用法三、结构体数组和指针四、结构体指针五、包含结构体的结构体六、链表七、静态链表八、动态链表一、结构体的概念 比如说学生的信息,包含了学生名称、学号、...
    99+
    2024-04-02
  • 详解C语言之单链表
    目录一、思路步骤1. 定义结构体2.初始化3.求当前数据元素的个数4.插入5.删除6.释放内存空间二、代码总结 一、思路步骤 1. 定义结构体 a.数据域:用来存放数据 b.指针域...
    99+
    2024-04-02
  • C++数据结构之单链表
    目录单链表结构的定义单链表打印动态申请一个结点单链表尾插单链表尾删单链表头插单链表头删求单链表长度单链表查找单链表在pos位置插入单链表在pos后面位置插入单链表删除pos位置单链表...
    99+
    2024-04-02
  • Java集合类之TreeSet的用法详解
    目录上节回顾TreeSet集合概述和特点构造方法方法摘要Demo自然排序Comparable的使用比较器排序Comparator的使用上节回顾 LinkedHashSet集合概述及特...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作