Home » Data Structures, Linked List, Programming

Understanding Linked Lists – Part 2

25 October 2009 No Comment

The following code is for the ListNode class of List node objects. This example list program is built for storing strings. The list node class given here has two data members viz., Data and Link. Data is of the type string to store list item in it and Link is again of the type ListNode to refer next node in the list.

Though .Net contains inbuilt classes for creating linked lists, the recoded C# program given here is to help the readers to understand how the linked lists are really working. Readers can put these class code into a new project in C#.Net. For testing, the required test harness has to be setup in their code. They can convert the class code to any other language easily since the code doesn’t contain any .Net or C# specific features.

namespace ListLibrary
{
    class ListNode
    {
        // Data and Link part of the node
        private string mData;
        private ListNode mLink;
        // Constructor to initialize ListNode Object with default values
        public ListNode()
        {
            mData = "";
            mLink = null;
        }
        // Constructor to initialize ListNode Object with parameter passed
        public ListNode(string val)
        {
            mData = val;
            mLink = null;
        }
        // Property: Data
        public string Data
        {
            get
            {
                return mData;
            }
            set
            {
                Data = value;
            }
        }
        // Property: Link
        public ListNode Link
        {
            get
            {
                return mLink;
            }
            set
            {
                mLink = value;
            }
        }
    }
}

Linked list operations implemented in C# as follows

namespace ListLibrary
{
    class MyLinkedList
    {
        // Head refers to the first node in the list and
        // Tail refers to the last node
        private ListNode mHead, mTail;
        private int mCount;

        // Constructor to initialize Head and Tail with null
        public MyLinkedList()
        {
            mHead = mTail = null;
        }

        // Inserts a ListNode at first position
        public void InsertAtFront(string val)
        {
            // Create a ListNode with the value passed
            ListNode NewNode = new ListNode(val);

            // Get the existing first node in the link of new ListNode
            // So, the current first node will become the second node
            NewNode.Link = mHead;

            // Make the Head to refer new ListNode
            mHead = NewNode;

            // If intitially list is empty make the tail to refer first node
            if (mTail == null) mTail = NewNode;

            // Increment the counter
            mCount++;
        }

        // Inserts a ListNode at last position
        public void InsertAtLast(string val)
        {
            // Create a ListNode with the value
            ListNode NewNode = new ListNode(val);

            // If the list is empty insert the new node at first
            if (mHead == null)
                mHead = NewNode;
            else
                // else insert the new node as a link of last node
                mTail.Link = NewNode;

            // Make the Tail to refer new last node
            mTail = NewNode;

            // Increment the counter
            mCount++;
        }

        // Inserts a ListNode after the specified existing ListNode
        public bool InsertAfter(string val, string Searchval)
        {
            // If the list is empty return failure
            if (mHead == null)
                return false;

            // Set the traversal reference to refer the first node
            ListNode Traverse = mHead;

            // Traverse until it reaches last node
            while (Traverse != null)
            {
                // If the specified node found during traversal
                // insert the new node next to it
                if (Traverse.Data == Searchval)
                {
                    // Create a Listnode with the given value
                    ListNode NewNode = new ListNode(val);

                    // Make the link of the new node to refer link of
                    // the node found during search
                    NewNode.Link = Traverse.Link;

                    // Make the link of the searched node to refer New node
                    Traverse.Link = NewNode;

                    // If the found node is the last node, update the Tail
                    // to refer new node
                    if (Traverse == mTail) mTail = NewNode;

                    // Increment the counter
                    mCount++;

                    // return success
                    return true;
                }
                // Move to the next node in the list (traverse)
                Traverse = Traverse.Link;
            }
            return false;
        }

        // Inserts a ListNode before to a specfied existing ListNode
        public bool InsertBefore(string val, string Searchval)
        {
            // If list is empty return failure
            if (mHead == null) return false;

            // Traversal reference and Follower references
            ListNode Traverse, Follower;

            // If the first node is the listnode which we are searching for
            if (mHead.Data == Searchval)
            {
                // Create a NewNode with the given value
                ListNode NewNode = new ListNode(val);               

                // Make the NewNode to refer current first node
                NewNode.Link = mHead;

                // Make the NewNode as a first node
                mHead = NewNode;

                // Increment the count
                mCount++;

                // Return Success
                return true;
            }

            // Else start the traversal from the first node
            Traverse = mHead;

            // traverse loop
            while (true)
            {

                // Make the follower to refer current node
                Follower = Traverse;

                // Make the next node as current node
                Traverse = Traverse.Link;

                // If next node not exists (null) return failure
                if (Traverse == null) return false;

                // If the data found during the traversal
                if (Traverse.Data == Searchval)
                {
                    // Create a ListNode with the given value
                    ListNode NewNode = new ListNode(val);

                    // Make the NewNode to refer traverse(current) node
                    NewNode.Link = Traverse;

                    // Make the follower to refer new node
                    // since we need to insert the NewNode before the Searched Node
                    Follower.Link = NewNode;

                    // Increment the count
                    mCount++;

                    // Return success
                    return true;
                }
            }
        }
        // Traverse type 1 - Return the result in a string
        public string GetItemsInString()
        {
            // Form an empty string to have the result
            string ItemsInList = "";           

            // Traverse from the first node
            ListNode Traverse = mHead;

            // traverse until last node is reached
            while (Traverse != null)
            {
                // get the data and add to the string, delimit with a comma
                ItemsInList += "," + Traverse.Data;

                // Move to the next node
                Traverse = Traverse.Link;
            }

            // if string formed remove the intitial delimiter
            if (ItemsInList != "") ItemsInList = ItemsInList.Remove(0, 1);

            // return the result
            return ItemsInList;
        }

        // Traverse type 2 - Return the result in an array
        public string[] GetItemsInArray()
        {
            // If the list is empty return null
            if (mCount == 0) return null;

            // Form an array of size Count
            string[] ItemsInList = new string[mCount];

            // Start from the first node
            ListNode Traverse = mHead;

            // Set the index to first position
            int pos = 0;

            // Traverse until last node found
            while (Traverse != null)
            {
                // Copy the data in the array at given position
                ItemsInList[pos] =  Traverse.Data;

                // increment the position
                pos++;

                // Move to the next node in the list
                Traverse = Traverse.Link;
            }

            // return the array
            return ItemsInList;
        }

        // Removes a ListNode with given value from the list
        public bool Remove(string val)
        {
            // If the list is empty return failure
            if (mHead == null) return false;           

            // Start from the first node
            ListNode Traverse = mHead;
            ListNode Follower;

            // if the first node contains the value to be removed
            if (mHead.Data == val)
            {
                // If list is having only one value
                // make the Tail also null
                if (mTail == mHead) mTail = null;

                // make the head to refer second node
                // First node will be automatically deleted from memory
                // once it looses all references
                mHead = mHead.Link;

                // decrement the count
                mCount--;

                // Return success
                return true;
            }
            // Else repeat the loop
            while (true)
            {
                // Make the follower to refer current node
                Follower = Traverse;

                // Move to the next node in the list
                Traverse = Traverse.Link;

                // if next node not found return failure
                if (Traverse == null) return false;

                // If the value found at the current node
                if (Traverse.Data == val)
                {
                    // Make the follower to refer next node of
                    // the current node
                    Follower.Link = Traverse.Link;

                    // If the current node last node,
                    // make the Tail to refer follower node
                    if (mTail == Traverse) mTail = Follower;

                    // Decrement the count
                    mCount--;

                    // Return success
                    return true;
                }
            }
        }
        // Reverses all the items in the list
        public void Reverse()
        {

            // If the list is empty  return failure
            if (mHead == null) return;

            // Form three nodes required for reversing the list
            // Let the first temp reference refer first node
            ListNode tmpNode1 = mHead, tmpNode2 = null, tmpNode3 = null;

            // Tail becomes refering first node
            mTail = mHead;

            // while first reference not empty (reaches last node)
            while (tmpNode1 != null)
            {
                // Swap the three nodes successively
                mHead = tmpNode1;
                tmpNode2 = tmpNode1.Link;
                tmpNode1.Link = tmpNode3;
                tmpNode3 = tmpNode1;
                tmpNode1 = tmpNode2;
            }
        }

        // Free memory allocated for List
        ~MyLinkedList()
        {

            // Move the head towards last node
            // Makes successive nodes' references killed
            // Once all the references removed
            // memory automatically recovered by .Net framework
            while (mHead != null)
            {
                mHead = mHead.Link;
            }
            mTail = null;
        }
    }
}
Line Break

Author: Ganesh Kumar (15 Articles)

Ganesh Kumar

Ganesh Kumar has qualified with his Masters in Technology with Distinction. His total experience is about 6 years in Development and 2 years in Teaching. Presently he is working for WDC Ltd., Kolkata, India in C#, .Net and SQL Server.

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.

Spam protection by WP Captcha-Free

Get Adobe Flash playerPlugin by wpburn.com wordpress themes