集合之链表

LinkedList<T>是一个双向链表,其元素指向它前面和后面的元素。

优点:如果将元素插入到列表的中间位置,使用链表就会非常快。在插入一个元素时,只需要修改上一个元素的Next引用和下一个元素的Previous引用,使它们引用所插入的元素。在List<T>类中,插入一个元素时,需要移动该元素后面的所有元素。

缺点:链表的元素只能一个接一个地访问,这需要较长的时间来查找位于链表中间或尾部的元素。

另外需要注意的一点:链表不能再列表中仅存储元素。存储元素时,链表还必须存储每个元素的下一个元素和上一个元素的信息。这也是为什么LinkedList<T>包含LinkedListNode<T>类型的元素的原因。

其中LinkedListNode<T>定义了属性List、Next、Previous和Value。List属性返回与节点相关的LinkedList<T>对象,Next和Previouss属性用于遍历链表,访问当前节点之后和之前的节点。value返回与节点相关的元素,其类型是T。

LinkedList<T>类定义的成员可以访问链表中的第一个和最后一个元素(First和Last)、在指定位置插入元素方法有AddAfter()、AddBefore()、AddFirst()和AddLast()方法,删除指定位置的元素有Remove()、RemoveFirst()和RemoveLast()方法,从链表的开头(Find()方法)或结尾(FindLast()方法)开始搜索元素。

书上有一个案例:大体流程是这样:添加一批文档,根据优先级和创建时间进行排序展示;

直接看书中的代码:

    /// <summary>
    /// 创建一个文档类
    /// </summary>
    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;
        }
    }
    /// <summary>
    /// 对文档进行链表存储处理
    /// </summary>
    public class PriorityDocumentManager
    {
        private readonly LinkedList<Document> _documentList;
        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)
        {
            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 ArgumentNullException("Priority must be between 0 and 9");
            }
            if (_priorityNodes[priority].Value == null)//不存在优先级节点
            {
                --priority;
                if (priority >= 0)//递归函数
                {
                    //检查下一个较低优先级
                    AddDocumentToPriorityNode(doc, priority);
                }
                else //现在不存在具有相同优先级或更低优先级的优先级节点,请将新文档添加到结尾
                {
                    _documentList.AddLast(doc);
                    _priorityNodes[doc.Priority] = _documentList.Last;
                }
                return;
            }
            else //存在优先级节点
            {
                LinkedListNode<Document> prioNode = _priorityNodes[priority];
                if (priority == doc.Priority)//存在具有相同优先级的优先级节点
                {
                    //相同优先级节点根据存储时间追加到节点之后
                    _documentList.AddAfter(prioNode, doc);
                    //设置优先级较低的节点
                    _priorityNodes[doc.Priority] = prioNode.Next;
                }
                else//仅存在具有较低优先级的优先级节点
                {
                    //获取优先级较低的第一个节点
                    LinkedListNode<Document> firstPrioNode = prioNode;
                    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:{doc.Priority},title:{doc.Title}");
            }
        }
    }
            //调用方式
            var 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.ReadLine();

看完书上的实现方式:

现在我们自己构造一个场景去实现它;

情景如下:书店老板进来一批书籍,有高尔基的《童年》、《在人间》、《我的大学》;老舍的《骆驼祥子》、《四世同堂》、《茶馆》;其他名人的相关书籍《C#编程艺术》、《WepApi的设计理念》、《MVC对WebForm的改进之处》;现在它们顺序是乱的;顺序如下:1.《童年》、2.《骆驼祥子》、3.《C#编程艺术》、4.《WepApi的设计理念》、5.MVC对WebForm的改进之处》、1.《在人间》、2.《四世同堂》、1.《我的大学》、2.《茶馆》;现在我们通过链表的方式对他们进行存储并归类,实现方式如下:

    /// <summary>
    /// 书
    /// </summary>
    public class Book
    {
        public int ID { get; set; }
        public string BookName { get; set; }
        public Book(int id, string bookName)
        {
            this.ID = id;
            this.BookName = bookName;
        }
    }
    public class BookManager<T> where T : Book
    {
        /// <summary>
        /// 链表集合
        /// </summary>
        private LinkedList<T> bookList;
        /// <summary>
        /// 队列集合
        /// </summary>
        private List<LinkedListNode<T>> books;
        public BookManager()
        {
            bookList = new LinkedList<T>();
            books = new List<LinkedListNode<T>>();
            for (int i = 0; i < 9; i++)
            {
                books.Add(new LinkedListNode<T>(null));
            }
        }

        public void AddBook(T model)
        {
            if (model == null) throw new ArgumentNullException("model");
            AddBookToNode(model, model.ID);

        }
        private void AddBookToNode(T model, int id)
        {
            if (books[id].Value == null)//该节点没有值
            {
                //递减查看是否有重复
                --id;
                if (id >= 0)
                    AddBookToNode(model, id);
                else//不存在相同的优先级,或更低的优先级的节点
                {
                    bookList.AddLast(model);
                    books[model.ID] = bookList.Last;
                }
                return;
            }
            else //存在优先级节点
            {
                LinkedListNode<T> prioNode = books[id];
                if (id == model.ID)//存在具有相同优先级的优先级节点
                {
                    //相同优先级节点根据存储时间追加到节点之后
                    bookList.AddAfter(prioNode, model);
                    //设置优先级较低的节点
                    books[model.ID] = prioNode.Next;
                }
                else//仅存在具有较低优先级的优先级节点
                {
                    //获取优先级较低的第一个节点
                    LinkedListNode<T> firstPrioNode = prioNode;
                    while (firstPrioNode.Previous != null && firstPrioNode.Previous.Value.ID == prioNode.Value.ID)
                    {
                        firstPrioNode = prioNode.Previous;
                        prioNode = firstPrioNode;
                    }
                    bookList.AddBefore(firstPrioNode, model);
                    //将优先级节点设置为新值
                    books[model.ID] = firstPrioNode.Previous;
                }
            }
        }
        public void DisplayAllNodes()
        {
            foreach (Book doc in bookList)
            {
                Console.WriteLine($"ID:{doc.ID},BookName:{doc.BookName}");
            }
        }
    }
            //调用方式
            var pdm = new BookManager<Book>();
            pdm.AddBook(new Book(1, "《童年》"));
            pdm.AddBook(new Book(2, "《骆驼祥子》"));
            pdm.AddBook(new Book(3, "《C#编程艺术》"));
            pdm.AddBook(new Book(4, "《WepApi的设计理念》"));
            pdm.AddBook(new Book(5, "《MVC对WebForm的改进之处》"));
            pdm.AddBook(new Book(1, "《在人间》"));
            pdm.AddBook(new Book(2, "《四世同堂》"));
            pdm.AddBook(new Book(1, "《我的大学》"));
            pdm.AddBook(new Book(2, "《茶馆》"));
            pdm.DisplayAllNodes();
            Console.ReadLine();

猜你喜欢

转载自blog.csdn.net/qq_31975127/article/details/85274793