Understanding Linked Lists – Part 2
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;
}
}
}









Author: Ganesh Kumar (15 Articles)
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!