使用C#的单链表实现 - RemoveLast方法

时间:2017-02-20 10:12:51

标签: c# singly-linked-list

我使用C#实现了Singly链表。任何人都可以查看下面的代码,并建议我错在哪里?

public int RemoveLast()
{
    if (Head != null)
    {
         var curNode = Head;

         while (curNode.Next != null)
         {
              curNode = curNode.Next;
         }

         var lastNodeValue = curNode.Value;

         curNode = null;
         Size--;
         return lastNodeValue;
     }

     return -1;
}

此功能不会删除最后一个节点。我无法弄清楚出了什么问题。当while循环结束时,我们在curNode中有节点的引用,其下一个为null。这意味着这是最后一个节点。最后,我将此节点设置为null。但是当我使用Display功能时。它还显示最后一个节点。这不是删除最后一个节点。

这是我的显示功能:

    public string Display()
    {
        if (Head == null)
        {
            return string.Empty;
        }

        var curNode = Head;
        var builder = new StringBuilder();

        while (curNode.Next != null)
        {
            builder.Append($"{curNode.Value} ");
            curNode = curNode.Next;
        }

        builder.Append($"{curNode.Value} ");

        return builder.ToString();
    }

4 个答案:

答案 0 :(得分:2)

您需要转到最后一个节点,并将其Next更改为null:

public int RemoveLast()
{
    if (Head != null)
    {
        var curNode = Head;

        while (curNode.Next?.Next != null)
        {
            curNode = curNode.Next;
        }

        var lastNodeValue = curNode.Next?.Value ?? -1;
        curNode.Next = null;
        Size--;
        return lastNodeValue;
    }

    return -1;
}

请注意,如果您还希望将Head设置为null(如果它是唯一的节点),那么您可以这样做:

public int RemoveLast()
{
    if (Head != null)
    {
        var curNode = Head;

        while (curNode.Next?.Next != null)
        {
            curNode = curNode.Next;
        }

        int lastNodeValue;

        if (Head.Next == null)
        {
            lastNodeValue = Head.Value;
            Head = null;
        }
        else
        {
            lastNodeValue = curNode.Next?.Value ?? -1;
        }
        curNode.Next = null;
        Size--;
        return lastNodeValue;
    }

    return -1;
}

我不得不说,这个Head属性看起来有点可疑 - 它应该属于另一个类。

答案 1 :(得分:1)

[x] -> [x] -> [x] -> null
               ^
               curNode (becomes null)
           ^
           this reference still exists

执行curNode = null时,您不会更改列表中的任何引用。 curNode变量仅被更改,它指向操作前的最后一个元素,之后变为 null

尝试始终在最后一个节点之前保持对节点的引用:

public int RemoveLast()
{
    if (Head != null)
    {
        var curNode = Head;
        // Corner case when there is only one node in the list
        if (Head.Next == null)
        {
            Head = null;
            Size--;
            return curNode.value;
        }

        var beforeLastNode = curNode;
        curNode = curNode.Next;
        while (curNode.Next != null)
        {
            beforeLastNode = curNode;
            curNode = curNode.Next;
        }

        var lastNodeValue = curNode.Value;

        beforeLastNode.Next = null;
        Size--;
        return lastNodeValue;
    }

    return -1;
}

答案 2 :(得分:0)

您需要在上一个节点上使curNode.Next值为null。 'curNode'是一个局部变量,将其设置为null除了可能延长其GC寿命之外什么都不做。

public int RemoveLast()
{
    if (Head != null)
    {
         var curNode = Head;
         var previousNode = null;

         while (curNode.Next != null)
         {
              previousNode = curNode;
              curNode = curNode.Next;
         }

         var lastNodeValue = curNode.Value;

         if (previousNode == null)
             Head = null;
         else
             previousNode.Next = null;
         Size--;
         return lastNodeValue;
     }

     return -1;
}

答案 3 :(得分:0)

好的,在你的帮助之后,我已经重写了满足所有要求的方法,如果链表中只有一个节点,则设置为HeadNode null。所以我们走了:

    public int RemoveLast()
    {
        if (HeadNode != null)
        {
            var currNode = HeadNode;
            var prevNode = HeadNode;

            if (HeadNode.Next == null)
            {
                HeadNode = null;
                Size--;
                return currNode.Value;
            }

            while (currNode.Next != null)
            {
                prevNode = currNode;
                currNode = currNode.Next;
            }

            prevNode.Next = null;
            Size--;
            return currNode.Value;
        }

        return -1;
    }

谢谢大家在这个帖子中做出的贡献。快乐编码:)