0

I've implemented Singly linked list using C# . Can anyone please look into the following code and suggest where I'm wrong?

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;
}

This function does not remove the last node. I'm unable to figure out what's wrong. When while loop ends, we have the reference of node in curNode whose next is null. It means this is the last node. At the end, I'm setting this node to null. But when I use Display function. It displays the last node as well. This is not deleting the last node.

Here is my display function:

    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();
    }
12
  • 1
    You are just clearing your currNode. It doesn't delete anything from the list. Expected bahavior. You'd have to clear the Next property of your second last Node to delete the last node. Commented Feb 20, 2017 at 10:15
  • 3
    You're not changing a .Next property to null. You're just changing a local reference to null. Commented Feb 20, 2017 at 10:15
  • My guess is that curNode is a local copy of the List Element. Not the actuall list Element. Having curNode being a var makes it ambigious what type it is. You should propably repalce it with explicit typisation. Taht is exactly the kind of case where you should not use var. Commented Feb 20, 2017 at 10:16
  • try to change your while to check the curNode.Next.Next == null and set curNode.Next = null Commented Feb 20, 2017 at 10:17
  • @SebastianL what if size = 1 ? currNode.Next.Next will throw an NPE! Commented Feb 20, 2017 at 10:19

4 Answers 4

2

You need to go to the last-but-one node, and change its Next to 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;
}

Note that if you also want Head to be set to null if its the only node, then you can do that like so:

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;
}

I have to say though, this Head property looks a bit dubious - it should perhaps belong to a different class.

Sign up to request clarification or add additional context in comments.

3 Comments

In case of size=1 , Head Node will not be removed, right?
@Fildor Yes, this issue here is this strange Head property. We can't really deal with that because we don't know what it is. So Head won't be altered. But I'll add an example saying what to do if it's needed.
After edit: Better but still not removing Head. I suspect it is a referecne in the list to the first Node, but you are right, OP should let us know. I'd add a check after the while: if( curNode == Head) Head = null;
1
[x] -> [x] -> [x] -> null
               ^
               curNode (becomes null)
           ^
           this reference still exists

When doing curNode = null you do not change any reference in the list. curNode variable is changed only, it is pointing to the last element before operation and becomes null afterwards.

Try always keep reference to the node before last:

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;
}

Comments

0

You need to make the curNode.Next value null on the previous node. 'curNode' is a local variable, setting it null doesn't do anything except maybe extend its GC life.

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;
}

1 Comment

Here also: What if size == 1?
0

okay guys, after your help, I've rewritten this method that meets all the requirements and set to HeadNode null if there is only one node in linked list. So here we go:

    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;
    }

Thank you everyone who contributed in this thread. Happy Coding :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.