Removing linked list nodes I have this code to remove nodes in a linked list which have odd values. This works well but I want to fine tune it for better reading. Can you please suggest improvements?

public class MyLinkedList
{
    public int data;
    public MyLinkedList next;

    public MyLinkedList(int v)
    {
        this.data = v;
    }

    //public void add(int i)
    //{
    //    this.next = new MyLinkedList(i);
    //    this.next.next = null;
    //}

    public void printLL()
    {
        MyLinkedList mmm = this;
        while (mmm != null)
        {
            Console.Write(mmm.data);
            Console.Write("-&gt;");
            mmm = mmm.next;
        }
    }
}

public static void deleteOdd(ref MyLinkedList mll)
{
    MyLinkedList head, previous, curr;
    head = mll;
    while (head.data % 2 != 0)
    {
        head = head.next;
    }
    mll = head;

    previous = head;
    curr = previous.next;

    while (curr != null)
    {
        if (curr.data % 2 != 0)
        {
            previous.next = curr.next;
            curr = previous.next;
        }
        else
        {
            previous = previous.next;
            curr = curr.next;
        }
    }
}

static void Main(string[] args)
    {
        MyLinkedList myll1 = new MyLinkedList(1); MyLinkedList myll2 = new MyLinkedList(3);
        MyLinkedList myll3 = new MyLinkedList(4); MyLinkedList myll4 = new MyLinkedList(4);
        MyLinkedList myll5 = new MyLinkedList(5); MyLinkedList myll6 = new MyLinkedList(6);
        MyLinkedList myll7 = new MyLinkedList(5); MyLinkedList myll8 = new MyLinkedList(6);
        MyLinkedList myll9 = new MyLinkedList(6); MyLinkedList myll10 = new MyLinkedList(9);
        MyLinkedList myll11 = new MyLinkedList(11); MyLinkedList myll12 = new MyLinkedList(12);

        myll1.next = myll2; myll2.next = myll3; myll3.next = myll4; myll4.next = myll5;
        myll5.next = myll6; myll6.next = myll7; myll7.next = myll8; myll8.next = myll9;
        myll9.next = myll10; myll10.next = myll11; myll11.next = myll12; myll12.next = myll12; myll12.next = null;


    myll1.printLL();
    Console.WriteLine();
    deleteOdd(ref myll1);
    Console.WriteLine();
    myll1.printLL();
}
Simple Commentary


The MSDN provides some naming conventions, the relevant bit being that public members should be ProperCamelCase (e.g. Data, not data).
Public Members, and types, should ideally have at least minimal inline documentation (\\\) to make it perfectly clear how to consume the API.
It's usually for the best to strip out old (commented) code. It has a habit of not being maintained and becoming incompatable with the code that is there. It also adds clutter.
For 'export' code, it's rarely useful to have methods which explicitly write to the console: much more useful to have something that writes to an abstract TextWriter (which can take Console.Out or a StreamReader), or that just returns a string. These give the consumer many more options.
deleteOdd(ref MyLinkedList) probably can't cope with empty lists (being passed them or returning them).
printLL isn't a great variable name: what is "LL"? It's a member of MyLinkedList, so the "LL" bit is redundant; I spect a while trying to work out if it was something to do with printing left to right or something.
mmm isn't a great variable name either: I can only assume it was meant to be mll!




Alternative implementation

Below are some methods which just about tally with yours, but using LinkedList&lt;T&gt;, and incorporating some of the suggestions above.

I don't know if you have a particular reason for needing a custom LinkedList implementation (not suggested by the code), but you can implement your methods tidily with .NET's built in LinkedList&lt;T&gt;, which could be argued to provide a nicer API. Crucially, it wraps up a linked list of LinkedListNode&lt;T&gt;s under a LinkedList&lt;T&gt;, which allows some (illusion of) separation of concerns, and spares you having to keep track of the head of the list explicitly. It also allows you to have an 'empty' list, which is good.

Delete Odd

This method is considerably shorter than before, and doesn't require a ref parameter. This works with empty lists. This is a much more understandable implementation, and much harder to 'get wrong', because of the API for LinkedList&lt;T&gt;.

/// &lt;summary&gt;
/// Removes odd elements from a LinkedList of integers
/// &lt;/summary&gt;
public static void DeleteOdd(LinkedList&lt;int&gt; ll)
{
    LinkedListNode&lt;int&gt; cur = ll.First; // grab first node

    while (cur != null)
    {
        var next = cur.Next; // make a note of the next node (will be null if cur is the last element)

        if (cur.Value % 2 != 0)
        {
            ll.Remove(cur); // remove the current node if odd
        }

        cur = next; // advance to the next node
    }
}


printLL

Here are two possible alternatives, which don't depend explicitly on Console: one just produces a string, the other prints to a TextWriter (sadly there is no better interface). These are both extension methods for LinkedList&lt;T&gt;, but there is no particular need for this.

/// &lt;summary&gt;
/// Renders a linked list as a string
/// &lt;/summary&gt;
public static string Render&lt;T&gt;(this LinkedList&lt;T&gt; ll)
{
    StringBuilder sb = new StringBuilder();

    foreach (var e in ll)
    {
        sb.Append(e.ToString());
        sb.Append("-&gt;");
    }

    return sb.ToString();
}

/// &lt;summary&gt;
/// Prints a linked list to a TextWriter, optionally appending a NewLine
/// &lt;/summary&gt;
public static void Print&lt;T&gt;(this LinkedList&lt;T&gt; ll, TextWriter textWriter, bool newLine = true)
{
    foreach (var e in ll)
    {
        textWriter.Write(e.ToString());
        textWriter.Write("-&gt;");
    }

    if (newLine)
        textWriter.WriteLine();
}


I wouldn't necessarily condone having the newLine parameter being optional, or indeed being there at all: this is just for illustration of some options. It would probably be better to have both Print and PrintLine if you need both.

Example usage

Note the nicer API for building a LinkedList&lt;T&gt;.

private static void ExampleUsage()
{
    LinkedList&lt;int&gt; ll = new LinkedList&lt;int&gt;();
    ll.AddLast(1);
    ll.AddLast(2);
    ll.AddLast(3);
    ll.AddLast(4);
    ll.AddLast(5);

    Console.WriteLine(ll.Render());
    ll.Print(Console.Out);
    DeleteOdd(ll);
    Console.WriteLine(ll.Render());
    ll.Print(Console.Out);
}