Tuesday, November 18, 2008

LAB ACTIVITY

Advantage of Linked Lists.

Linked lists are used to store collections of data. But we've already seen a mechanism for doing this. i.e. A collection of data can be stored in array. However, an array is a sequential structure meaning that it is a group of memory elements located in contiguous locations (located next to one another in a group). You need to know how many elements there will be and you need to allocate a block of memory for them.

When you don't know how many elements there will be, and if elements need to be inserted and deleted frequently, it is better to use a linked list. This is because each element for a linked list is created as needed and can be stored anywhere in the free memory space - the elements in the list do not have to be stored in contiguous locations.

Each element in a linked list is referred to as a node. In a simple singly linked list, each element has two fields:

  • Data member - contains the data (in our implementation, this is called datum)
  • Link member - contains the pointer to the next node (in our implementation, this is called next)
  • Note: we are going to represent the "link" part as "next" variable
In this lab, a node is defined by the following class (called Node):
class Node
{
private:
int data;
Node* next;

public:

Node();

void insertItem (int);
void makeList ();
void appendItem (int);
void deleteItem (int);
void printList ();
};

A couple of notes on linked lists are:

  • if you were implementing a doubly linked list, the above class would have an additional data member to define a pointer to the previous node.
  • the last node in any linked list contains a null pointer in the link member.
  • the null pointer is used to determine the end of the list.
  • notice that there is a constructor in the above implementation that can be used to set the datum and next members.

The following diagram illustrates a simple singly linked list.

In this lab, we use a class Node to create a linked list.

Operations on Linked Lists.

What follows here, are very rough algorithms on the basic operations that you would perform on a linked list. In actually implementing list operations, you would have to consider conditions such as: Is the list empty? What happens if I get to the null pointer and haven't found a data member that is supposed to be in the list? The algorithms here are just to provide you with an overview of the concepts involved in simple operations.
  • Creating a List (makeList())
                   First, create a node initialized with a data value and a NULL pointer.
    Set the "head" to point to the first node.
    Set up a current-pointer to the first node (or "head").
    Get a data value for the next node.
    While more nodes to add
    {
    Create a new node initialized with the data value and a NULL pointer.
    Set the current-pointer link member ("next") to the new node.
    Set the current-pointer to point to the new node.
    Get a data value for the next node.
    }
  • Adding a Node (appendItem(int item))
                   //Find the end of the list...
    Set a current-pointer to the "head".
    While current-pointer link member ("next") is not NULL
    {
    Set the current-pointer to the "next" node in the list.
    }
    //Now current-pointer points to the last node...
    Create a new node initialized with the "item" and a NULL pointer.
    Set the current-pointer link member ("next") to this new node.
  • Printing Nodes (printList())
                   Set a current-pointer to the "head".
    While current-pointer is not NULL
    {
    Print the data member ("datum") of the current node
    Set the current-pointer to the "next" node in the list.
    }
  • Inserting Nodes (insertItem(int item))
    This algorithm assumes that you want to insert a node into a list of ordered values. Let's say you have two values, 12 and 24. A new value of 14 should be inserted between these existing values so that the final list will contain the values 12, 14, and 24.
                   Set a previous-pointer to NULL.
    Set a current-pointer to the "head".
    //Find where your want to insert into the list...
    While the new data member > current-pointer value
    {
    //Move both pointers along in the list...
    Set the previous-pointer to the current-pointer
    Set the current-pointer to the "next" node in the list.
    }
    Create a new node initialized with the "item" and current-pointer.
    Set the link member in the previous_pointer to the new node.
    This is much easier to understand if you visualize the nodes and the pointers as they are changed. The following diagram attempts to illustrate this process.
  • Deleting Nodes (deleteItem(int item))

    This routine assumes that the item you are searching for is, in fact, in the list.

                   If "item" is in the first node
    {
    Set a delete-pointer to the first node.
    Change the "head" pointer to the second node.
    }
    Else
    {
    Set a current-pointer to the "head".
    While current-pointer->next->datum is not equal to "item"
    {
    Set the current-pointer to the "next" node in the list.
    }
    Set a delete-pointer to the node to be deleted (Note: it is
    the node after current-pointer).
    Set the link member ("next") of the current-pointer to the
    "next" node after delete-pointer.
    }
    Delete the node indicated by delete-pointer.
    This is much easier to understand if you visualize the nodes and the pointers as they are changed. The following diagram attempts to illustrate this process.

No comments: