Add an Node by index to custom LinkedList, with shift to right

Viewed 66

I faced a very weird problem. I can`t insert a node by index into a custom linked list. So here it is my method:

public void Insert(int index, T item)
    {
        if(item == null)
            throw new ArgumentNullException(nameof(item), "Item is equal null.");

        if (index > Count || index < 0)
            throw new ArgumentOutOfRangeException(nameof(index),"Index out of range.");

        Item<T> newNode = new Item<T>(item);
        Item<T> currentItem = Head;

        if (index == 0)
        {
            newNode.Next = Head;
            return;
        }

        var x = FindItemByData(this[index]);

        while (currentItem.Next != null)
        {
            if (currentItem.Next == x)
            {
                currentItem.Next = newNode;
                newNode.Next = FindItemByData(this[index]);
            }

            currentItem = currentItem.Next;
        }
    }

And there are Item class:

public class Item<T>
   {
       public T Data { get; set; }
       public Item<T> Next { get; set; }
       public Item(T data)
       {
           Data = data;
           Next = null;
       }
   }

Indexator of my linked list returns a data from specify node in the list, so I need to insert a new node to list with data: item. For example: I have a list of items ⛑ . And I need to insert on index 1 - element , result list might be ⛑ .

I tried to show that this problem doesn't simple because I can`t found a solution for insertion by index, there are always only 'Insert before'.

The method that I implemented doesn't work. Hopefully, someone can help me with this.

Also, there the test to this method:

        [TestCase(0)]
        [TestCase(5)]
        [TestCase(2)]
        public void Insert_AtPositionValue_ReturnCount(int position)
        {
            //arrange
            CustomList<int> list = new CustomList<int>(1, 2, 7, 8, 10);

            //act
            int elementToInsert = 100;
            list.Insert(position, elementToInsert);
            int count = list.Count;

            int actualValue = list[position];


            //arrange
            Assert.Multiple(() =>
            {
                Assert.AreEqual(elementToInsert, actualValue, message: "Insert or Get Count  work incorrectly ");
                Assert.AreEqual(6, count, message: "Insert or Get Count  work incorrectly ");
            });
        }
2 Answers

I think you are iterating the list two times, one with FindItemByData and one to recatch the item in the while.

You also forgot to append the rest of the list to the new node.

public void Insert(int index, T item)
{
    if(item == null)
        throw new ArgumentNullException(nameof(item), "Item is equal null.");

    if (index > Count || index < 0)
        throw new ArgumentOutOfRangeException(nameof(index),"Index out of range.");

    Item<T> newNode = new Item<T>(item);
    Item<T> currentItem = Head;

    if (index == 0)
    {
        
        newNode.Next = Head;
        Head = newNode; //you forgot this. You have to reset the head of the list.
        return;
    }

    //delete this <var x = FindItemByData(this[index]);>

    
    for (int i = 0; i<index-1; i++) //if index == 1 I want to add right after head
    {
        currentItem = currentItem.Next;
    }

    newNode.Next = currentItem.Next; //append the rest of the list after newNode
    currentNode.Next = newNode; //insert new node after the current node
}

Actually the previous author was close. But the error was in passing links to the next element.

public void Insert(int index, T item)
        {
            if (item == null)
                throw new ArgumentNullException(nameof(item), "Item is equal null.");

            if (index > Count || index < 0)
                throw new ArgumentOutOfRangeException(nameof(index), "Index out of range.");

            Item<T> newNode = new Item<T>(item);
            Item<T> currentItem = Head;

            if (index == 0)
            {
                newNode.Next = Head;
                Head = newNode;
                Count++;
                return;
            }

            for (int i = 0; i < index - 1; i++) 
            {
                currentItem = currentItem.Next;
            }

            newNode.Next = currentItem; 
            currentItem.Next = newNode;
            Count++;
        }
Related