首页 > 解决方案 > DoubleLinkedList C#删除最后两个元素

问题描述

我试图修复一个代码,它是一个 LinkedList。任务是删除列表的最后 X 个元素。我用 RemoveRange 尝试过,但 VS 不接受我的解决方案并说 RemoveRange 不存在。

var list = new DoublyLinkedList<string>();
list.Add("A");
list.Add("B");
list.Add("C");
list.Add("D");
list.Add("E");
list.RemoveLast(2);

这是程序(主)中的代码。在第二个类中应该有方法 RemoveLast,但我没有得到工作代码。有人可以解释一下,我是如何获得 RemoveLast 的?

using System;
using System.Collections;
using System.Collections.Generic;

namespace Test
{
    public class DoublyLinkedList<T> : IEnumerable<T>
    {    
        public void RemoveLast(int v)
        {
            int remove = Math.Max(0, this.Count - v);

            this.RemoveRange(v, this.Count - v);              
        }
     }
}

RemoveRange 带有红色下划线

感谢您的帮助!

完整的双链表:

`using System;
using System.Collections;
using System.Collections.Generic;

namespace Test
{
    public class DoublyLinkedList<T> : IEnumerable<T>
    {
        public void RemoveLast(int v)
        {
            int remove = Math.Max(0, this.Count - v);

            this.RemoveRange(v, this.Count - v);



        }

        private sealed class Node
        {
            public T Item { get; set; }
            public Node Previous { get; set; }
            public Node Next { get; set; }
        }

        private Node first, last;

        public int Count { get; private set; }

        public void Add(T item)
        {
            Node newItem = new Node() { Item = item, Next = null, Previous = null };

            if (first == null)
            {
                first = newItem;
                last = newItem;
            }
            else
            {
                last.Next = newItem;
                newItem.Previous = last;

                last = newItem;
            }
            Count++;
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            Node node = first;

            while (node != null)
            {
                yield return node.Item;
                node = node.Next;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<T>)this).GetEnumerator();
        }

        public override string ToString()
        {
            string s = "";

            Node node = first;

            while (node != null)
            {
                s += node.Item.ToString() + " -> ";
                node = node.Next;
            }
            s += "Count: " + Count.ToString();

            return s;
        }

        private Node find(T item)
        {
            Node node = first;

            while (node != null)
            {
                if (node.Item.Equals(item))
                    return node;

                node = node.Next;
            }
            return null;
        }

        private Node findPrevious(T item)
        {
            Node previousNode = null;
            Node node = first;

            while (node != null)
            {
                if (node.Item.Equals(item))
                    return previousNode;

                previousNode = node;
                node = node.Next;
            }
            return null;
        }
    }
}`

标签: c#listlinq

解决方案


你知道已经有一个双链表类,不是吗? System.Collections.Generic.LinkedList?我的建议是使用该类。

如果重新设计代码的工作量太大,例如因为您的 DoublyLinkedList 已经被大量使用,我的建议是让 DoublyLinkedList 成为 LinkedList 的适配器:

class DoublyLinkedList<T> : IEnumerable<T>, IEnumerable
{
    private readonly LinkedList<T> linkedList = new LinkedList<T>();

    public int Count => this.linkedList.Count;

    public void Add(T item)
    {
        this.LinkedList.Add(item);
    }

    public IEnumerator<T> GetEnumerator()
    {
        return this.LinkedList.GetEnumerator();
    }

    ... // etc.
}

您需要添加一种方法来从列表中删除最后 N 项。例如 RemoveLast(10) 应该从你的双向链表中删除最后 10 个元素。如果您的列表包含 10 个或更少的元素,这将清除您的完整列表。

void Clear()
{
    this.LinkedList.Clear();
}

void RemoveLast()
{
    if (this.LinkedList.Count != 0)
        this.linkedList.RemoveLast();
}

void RemoveLast(int removeCount)
{
    if (this.Count <= removeCount)
    {
        this.linkedList.Clear();
    }
    else
    {
        for (int i=0; i<removeCount; ++i)
        {
            this.RemoveLast();
        }
    }
}

可能是您的主管很固执,没有按照您的建议重用经过全面测试的可信赖 .NET 类。在这种情况下,您将不得不更改RemoveLast()方法。

void Clear()
{
    this.first = null;
    this.last = null;
    this.count = 0;
}

void RemoveLast()
{
    switch (this.Count)
    {
        case 0:
            // empty list; do nothing
            break;
        case 1:
            // removing the last element of the list
            this.Clear();
            break;

       default:
           var lastNode = this.last;

           // because more than one element I'm certain there is a previous node
           var previousNode = lastNode.Previous;
           var previousNode.Next = null;
           this.last = previousNode;
           --this.count;
           break;
    }
}

推荐阅读