Unsorted List Implemented as a linked structure in C++
Header file for a list class
//---------------------------------------------------------------
// File: Code112_List.h
// Purpose: Header file for a demonstration of an unsorted list
// implemented as a linked structure.
// Programming Language: C++
// Author: Dr. Rick Coleman
//---------------------------------------------------------------
#pragma once;
#include <iostream>
using namespace std;
// Define a structure to use as the list item
struct ListItem
{
int key;
float theData;
ListItem *next;
};
class Code112_List
{
private:
ListItem *head; // Pointer to head of the list
public:
Code112_List(); // Class constructor
~Code112_List(); // Class destuctor
void ClearList(); // Remove all items from the list
bool Insert(int key, float f);// Add an item to the list
ListItem *Delete(int key); // Delete an item from the list
ListItem *Search(int key); // Search for an item in the list
int ListLength(); // Return number of items in list
bool isEmpty(); // Return true if list is empty
bool isFull(); // Return true if list is full
void PrintList(); // Print all items in the list
};
Implementation (.cpp) file for a list class
//---------------------------------------------------------------
// File: Code112_List.cpp
// Purpose: Implementation file for a demonstration of an unsorted
// list implemented as a linked structure.
// Programming Language: C++
// Author: Dr. Rick Coleman
//---------------------------------------------------------------
#include "Code112_List.h"
//--------------------------------------------
// Function: Code112_List()
// Purpose: Class constructor
// Returns: void
//--------------------------------------------
Code112_List::Code112_List()
{
head = NULL;
}
//--------------------------------------------
// Function: Code112_List()
// Purpose: Class destructor
// Returns: void
//--------------------------------------------
Code112_List::~Code112_List()
{
// Clear the list to free any memory being used
ClearList();
}
//--------------------------------------------
// Function: ClearList()
// Purpose: Remove all items from the list
// Returns: void
//--------------------------------------------
void Code112_List::ClearList()
{
ListItem *temp;
if(!isEmpty())
{
temp = head;
// Scan list and free all nodes
while(head != NULL)
{
temp = head;
head = head->next;
delete temp;
}
}
}
//--------------------------------------------
// Function: Insert()
// Purpose: Insert an item into the list at
// the end of the list. See alternate
// code below for insert at the beginning
// of the list.
// Returns: true if insertion was successful
// or false if the insertion failed.
//--------------------------------------------
bool Code112_List::Insert(int key, float f)
{
ListItem *temp, *newNode;
// Create a new node and insert the data
newNode = new ListItem();
// Check to see if memory allocation failed
if(newNode == NULL) return false;
// If all OK then insert the data
newNode->key = key;
newNode->theData = f;
newNode->next = NULL; // Very import to init this to NULL
// Check to see if the list is empty
if(isEmpty())
{
// Insert new node as first in the list
head = newNode;
}
else
{
// Find end of the list
temp = head;
while(temp->next != NULL)
temp = temp->next;
// Add this node to the end of the list
temp->next = newNode;
/* Alternate insertion code:
* Since this is an unsorted list an alternate
* insertion approach is to add the new node at
* the head of the list. To do this replace all
* of the code in the else part of this function
* with the following:
*
* newNode->next = head;
* head = newNode;
*/
}
return true; // Signal successful insertion
}
//--------------------------------------------
// Function: Delete()
// Purpose: Remove and return an item from
// the list.
// Returns: Pointer to the item removed or
// NULL if not found
//--------------------------------------------
ListItem *Code112_List::Delete(int key)
{
ListItem *temp, *back;
// Check for empty list
if(isEmpty()) return NULL;
// Search the list for the item to delete
temp = head;
back = NULL;
// The order of the two conditionals in the while()
// look is VERY important. You want to check first
// to see if temp is NULL before trying to reference
// the memory temp is pointing to. If temp is NULL
// then, because this is a && (AND) condition the
// second condition will never be tested. Testing
// the second condition when temp==NULL will result
// in a crash and burn.
while((temp != NULL) && (key != temp->key))
{
back = temp;
temp = temp->next;
}
// Check to see if the item was found
if(temp == NULL) return NULL; // Not found so return false
else if(back == NULL) // Check to see if item is first in list
{
head = head->next;
return temp; // Return the removed item
}
else // Delete node elsewhere in the list
{
back->next = temp->next;
return temp; // Return the removed item
}
return NULL; // Should not get here but this keeps the compiler from giving a warning.
}
//--------------------------------------------
// Function: Search()
// Purpose: Search for an item by key and copy
// the value into the variable pointed to
// by *retVal.
// Returns: Copy of the node if successful or
// false if failed.
//--------------------------------------------
ListItem *Code112_List::Search(int key)
{
ListItem *temp;
temp = head;
// See note on the order of the conditional in this
// while() loop in Delete() function above.
while((temp != NULL) && (key != temp->key))
{
temp = temp->next;
}
// If item not found or list is empty return NULL
if(temp == NULL) return NULL;
else
{
ListItem *retItem = new ListItem();
*retItem = *temp; // block copy the entire structure
retItem->next = NULL; // clear the pointer
return retItem; // Signal successful search
}
}
//--------------------------------------------
// Function: ListLength()
// Purpose: Return the number of items in the
// list.
// Returns: Number of items in list.
//--------------------------------------------
int Code112_List::ListLength()
{
ListItem *temp;
int count = 0;
temp = head;
while(temp != NULL)
{
temp = temp->next;
count++;
}
return count;
// An alternate way to do this is to maintain
// a static variable at the top of this source
// code, e.g. int count. This can be incremented
// each time a node is added and decremented each
// time a node is deleted.
}
//--------------------------------------------
// Function: isEmpty()
// Purpose: Return true if the list is empty
// Returns: true if empty, otherwise false
//--------------------------------------------
bool Code112_List::isEmpty()
{
return (head == NULL);
}
//--------------------------------------------
// Function: isFull()
// Purpose: Return true if the list is full
// Returns: true if full, otherwise false
// Note: In theory a linked list cannot be
// full (unless you run out of memory) so
// this function defaults to returning false.
//--------------------------------------------
bool Code112_List::isFull()
{
return false;
}
//--------------------------------------------
// Function: PrintList()
// Purpose: Print all items in the list with
// their priority.
// Returns: void
//--------------------------------------------
void Code112_List::PrintList()
{
ListItem *temp;
cout << "\n\nItems in the List\n";
cout << "-----------------------------------------------------------\n";
cout << "Key\t\tData\n";
cout << "-----------------------------------------------------------\n";
if(head == NULL) // Report no items in the list
{
cout << "\t List is currently empty.\n";
}
else
{
temp = head;
while(temp != NULL)
{
cout << temp->key << "\t\t" << temp->theData << "\n";
temp=temp->next;
}
}
cout << "-----------------------------------------------------------\n\n";
}
Main file used to test the list
//---------------------------------------------------------------
// File: ListMain.cpp
// Purpose: Main file with tests for a demonstration of an unsorted
// list implemented as a linked structure.
// Programming Language: C++
// Author: Dr. Rick Coleman
//---------------------------------------------------------------
#include "Code112_List.h"
int main(int argc, char **argv)
{
Code112_List *theList;
ListItem *theItem;
cout << "Simple List Demonstration\n";
cout << "(Unsorted list implemented as a linked structure.)\n\n";
cout << "Create a list and add a few items to the list";
theList = new Code112_List(); // Instantiate a list object
theList->Insert(5, 3.1f); // Note: The argument to the funtion should be a float
theList->Insert(1, 5.6f); // A constant real number like 3.1 is interpreted as
theList->Insert(3, 8.3f); // a double unless it is explicitly defined as a float
theList->Insert(2, 7.4f); // by adding an 'f' to the end of the number.
theList->Insert(4, 2.5f);
// Show what is in the list
theList->PrintList();
// Test the list length function
cout << "\nList now contains " << theList->ListLength() << " items.\n\n";
// Test delete function
cout << "Testing delete of last item in list.\n";
theItem = theList->Delete(4);
if((theItem != NULL) && (theItem->key == 4))
{
cout << "\tSuccessfully removed the last item in the list.\n";
delete theItem; // It is now our responsibility to delete it.
}
theList->PrintList();
// Test delete function
cout << "Testing delete of first item in list.\n";
theItem = theList->Delete(5);
if((theItem != NULL) && (theItem->key == 5))
{
cout << "\tSuccessfully removed the first item in the list.\n";
delete theItem; // It is now our responsibility to delete it.
}
theList->PrintList();
// Test delete function
cout << "Testing delete of a middle item in list.\n";
theItem = theList->Delete(3);
if((theItem != NULL) && (theItem->key == 3))
{
cout << "\tSuccessfully removed a middle item from the list.\n";
delete theItem; // It is now our responsibility to delete it.
}
theList->PrintList();
// Test delete function with a known failure argument
cout << "Testing failure to find item in delete function.\n";
if(theList->Delete(4) != NULL) // This one has already been removed
cout << "\tOops! Should not have been able to delete.\n";
else
cout << "\tUnable to locate item to delete.\n\n";
// Test search (known failure)
cout << "Testing Search function. Search for key 3 (not in the list).\n";
theItem = theList->Search(3);
if((theItem != NULL) && (theItem->key == 3))
{
cout << "\tSearch result for key 3: theData = %f\n\n", theItem->theData;
delete theItem; // It is now our responsibility to delete the duplicate returned.
}
else
cout << "\tSearch result for key 3: Unable to locate item in list\n\n";
// Test search (known success)
cout << "Testing Search function. Search for key 2 (in the list).\n";
theItem = theList->Search(2);
if((theItem != NULL) && (theItem->key == 2))
{
cout << "\tSearch result for key 2: theData = " << theItem->theData << endl << endl;
delete theItem; // It is now our responsibility to delete the duplicate returned.
}
else
cout << "\tSearch result for key 2: Unable to locate item in list\n\n";
cout << "\n\nEnd list demonstration...\n\n";
return 0;
}