The following program implements a linked list and the methods to manipulate it:

  • Removing the last element: RemoveLast()
  • Removing an element at a given index: RemoveAt(int k)
  • Checking if an element with a given key exists: Find(string item)
  • Removing an element following a given one: RemoveAfter(Node<string> node)
  • Inserting an element after a given one: InsertAfter(Node<string> node, Node<string> newNode)
  • Removing all elements with a given key: Remove(string item)
using System;

namespace ConsoleTest
{
    class Program
    {
        private static Node first;

        static void Main(string[] args)
        {
            first = PopulateList();

            Console.WriteLine("All items");
            ShowItems();

            Console.WriteLine("Remove last");
            RemoveLast();
            ShowItems();

            Console.WriteLine("Remove at 2");
            RemoveAt(2);
            ShowItems();

            Console.WriteLine("Insert C after B");
            var third = new Node { Item = "C" };
            InsertAfter(first.Next, third); // first.Next is B
            ShowItems();

            Console.WriteLine("Remove after B");
            RemoveAfter(first.Next); // first.Next is B
            ShowItems();

            Console.WriteLine("Find B: " + Find("B"));
            Console.WriteLine("Find C: " + Find("C"));
            Console.WriteLine();

            Console.WriteLine("Insert a few test items");
            InsertTestItems("X");
            ShowItems();

            Console.WriteLine("Remove all test items");
            Remove("X");
            ShowItems();

            Console.ReadKey();
        }

        static private void RemoveLast()
        {
            // Is the list empty?
            if (first == null)
                return;

            // Does the list have only one element?
            if (first.Next == null)
            {
                first = null;
                return;
            }

            // Determine the element before last.
            Node node = first;
            while (node.Next.Next != null)
                node = node.Next;

            // Remove the element.
            node.Next = null;
        }

        static private void RemoveAt(int k)
        {
            // Is the list empty?
            if (first == null)
                return;

            // Does the list have only one element?
            if (first.Next == null)
            {
                first = null; // remove the only element in the list
                return;
            }

            // Do we need to remove the first element?
            if (k == 0)
            {
                first = first.Next; // remove the first element
                return;
            }

            // Determine the element immediately before the k-th element.
            Node node = first;
            int n = 0;
            while (node.Next.Next != null && n < k - 1)
            {
                node = node.Next;
                ++n;
            }

            if (n == k - 1) // check if the requested element exists
            {
                // k-1 is node
                // k   is node.Next; this is the element we want to remove
                // k+1 is node.Next.Next
                node.Next = node.Next.Next; // remove the k-th element
            }
        }

        // Inserts a new node after the given node.
        static private void InsertAfter(Node node, Node newNode)
        {
            if (node == null || newNode == null)
                return;

            newNode.Next = node.Next;
            node.Next = newNode;
        }

        static private void RemoveAfter(Node node)
        {
            if (node == null)
                return;

            if (node.Next == null)
                return;

            node.Next = node.Next.Next;
        }

        // Removes all of the nodes that have the given item as its field.
        static private void Remove(string item)
        {
            // Is the list empty?
            if (first == null)
                return;

            Node prev = null;

            for (Node node = first; node != null; node = node.Next)
            {
                if (node.Item == item)
                {
                    if (prev != null)
                    {
                        prev.Next = prev.Next.Next;
                    }
                    else
                    {
                        // Remove the first element because prev == null.
                        first = first.Next;
                    }
                }
                else
                {
                    prev = node;
                }
            }
        }

        static private bool Find(string item)
        {
            // Is the list empty?
            if (first == null)
                return false;

            // Are we looking for the first node?
            if (first.Item == item)
                return true;

            Node node = first;
            while ((node = node.Next) != null)
            {
                if (node.Item == item)
                    return true;
            }

            return false;
        }

        // ShowItems traverses all the items in the list.
        static private void ShowItems()
        {
            for (Node node = first; node != null; node = node.Next)
            {
                Console.Write(node.Item.ToString() + " ");
            }
            Console.WriteLine("\n");
        }

        // PopulateList returns a reference to the first element.
        static private Node PopulateList()
        {
            var first = new Node();
            first.Item = "A";

            var second = new Node();
            second.Item = "B";
            first.Next = second;

            var third = new Node();
            third.Item = "C";
            second.Next = third;

            var fourth = new Node();
            fourth.Item = "D";
            third.Next = fourth;

            var fifth = new Node();
            fifth.Item = "E";
            fourth.Next = fifth;

            return first;
        }

        static private void InsertTestItems(string item)
        {
            // Insert a node at the beginning.
            Node oldFirst = first;
            first = new Node();
            first.Item = item;
            first.Next = oldFirst;

            // Insert two nodes at the end.
            Node last = first;
            while (last.Next != null)
                last = last.Next;

            var node1 = new Node();
            node1.Item = "X";
            last.Next = node1;

            var node2 = new Node();
            node2.Item = "X";
            node1.Next = node2;

            var node3 = new Node();
            node3.Item = "E";
            node2.Next = node3;

            var node4 = new Node();
            node4.Item = "X";
            node3.Next = node4;
        }

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

            public override string ToString() { return (Item == null ? "null" : Item.ToString()); }
        }
    }
}

Output:

All items
A B C D E

Remove last
A B C D

Remove at 2
A B D

Insert C after B
A B C D

Remove after B
A B D

Find B: True
Find C: False

Insert a few test items
X A B D X X E X

Remove all test items
A B D E