Computer Science 1622
Computer Science II

Laboratory Assignment 8
Strings
Due at the end of Lab

Introduction

Linked lists are the first abstract data structure to which you will be introduced. Linked lists are useful because they allow you to create only as much storage as is required and the order can of the data stored can be easily changed.

The first thing to be noticed with respect to linked lists is the data structure used to represent them. Typically a C struct is used to store the required data with an added field: next. The type of this field is a pointer to the same structure and is used to point to the next record in the linked list, or NULL if the node is the last one in the list. Below is an example of such a structure (taken from the program at the end of this lab):

typedef struct LLNODE_STRUCT
{
   float data;
   struct LLNODE_STRUCT *next;
} LLNode, *LLPtr;
There are two fields in this structure: data, which is the data to be stored in the linked list; in this case a floating-point number. (Note that you can have more than one field in a linked list structure to store data. If you wanted to store student information, for example, you may want to store the students name and ID number. This would require two fields: a char * and an int.) The second field in this structure is a pointer to the next node in the linked list. This is of type struct LLNODE_STRUCT * because the LLNode and LLPtr data types have not yet been declared at the time we need to declare the next field.

When a node is inserted into an empty list it becomes the head (or first element) of the list and its next field is set to NULL. To see how to insert a node after some other node in the list, consider the following diagram:

List
Start
 +-+    +---+-+    +---+-+
 + ---->| A | ---->| C | ---->(NULL)
 +-+    +---+-+    +---+-+
Say we would like to insert a new node B after node A in the list. First we need to set B's next field equal to A's next field (see the diagram below).

List
Start
 +-+    +---+-+    +---+-+
 + ---->| A | ---->| C | ---->(NULL)
 +-+    +---+-+    +---+-+
                   ^
		   |
New +-+    +---+-+ |
Node+ ---->| B | --+
    +-+    +---+-+
Next we set A's next field to point to node B (see the diagram below). If you follow the links though the list, you see that we have now inserted node B in between nodes A and C.

List
Start
 +-+    +---+-+    +---+-+
 + ---->| A | |    | C | ---->(NULL)
 +-+    +---+|+    +---+-+
           ---     ^
	   |       |
	   V       |
New +-+    +---+-+ |
Node+ ---->| B | --+
    +-+    +---+-+

Redrawing the picture this gives us the following list:

List
Start
 +-+    +---+-+    +---+-+    +---+-+
 + ---->| A | ---->| B | ---->| C | ---->(NULL)
 +-+    +---+-+    +---+-+    +---+-+

To delete node B from the above list, we first make a temporary pointer point to B:

List
Start
 +-+    +---+-+    +---+-+    +---+-+
 + ---->| A | ---->| B | ---->| C | ---->(NULL)
 +-+    +---+-+    +---+-+    +---+-+
                   ^
        +-+        |
    Gone+ ----------
        +-+

Then we set A's next equal to B's next field:

List            ---------------
Start           |             V
 +-+    +---+-+ |  +---+-+    +---+-+
 + ---->| A | ---  | B | ---->| C | ---->(NULL)
 +-+    +---+-+    +---+-+    +---+-+
                   ^
        +-+        |
    Gone+ ----------
        +-+
Then we can safely free the memory associated with node B by calling free on Gone. Redrawing the resulting list we get:

List
Start
 +-+    +---+-+    +---+-+
 + ---->| A | ---->| C | ---->(NULL)
 +-+    +---+-+    +---+-+

The Program

The program below defines a structure for a linked list node. Your job is to perform the following operations. After each step, print out the list by calling the printLList function and giving it the head of your list as its only parameter. For example, printLList(ListStart) will print out the linked list that is pointed to by ListStart.

The Code

#include <stdlib.h>
#include <stdio.h>

typedef struct LLNODE_STRUCT
{
   float data;
   struct LLNODE_STRUCT *next;
} LLNode, *LLPtr;


int main(void) {
   void printLList(LLPtr);
   LLPtr ListStart;
   
   printf("First insert operation:\n");
   /*
      First, write code to create a node to store the value 3.0 and
      print out the list using the printLList() function.
   */
   
   
   
   printf("\n");
   printf("Second insert operation\n");
   /*
      Now write code to create a node to store the value 6.0 and
      place it after the node that stores 3.0 (so the list is still
      in sorted order) and print out the list.
   */
   
 
 
   
   printf("\n");
   printf("Third insert operation\n");
   /*
      Now write code to create a node to store the value 1.0 and
      place it at the beginning of the list (so the list is still
      in sorted order) and print out the list.
   */
   
   
   
   
   printf("\n");
   printf("First delete operation\n");
   /*
   	Now write code to delete the node that contains the
   	value 3.0 from the list and print out the list.
   */
   
   
   
   
   printf("\n");
   printf("Second delete operation\n");
   /*
   	Finally, write code to delete the node that contains
   	the value 1.0 from the list and print out the list.
   */
   
   
   
   return 0;
}

void printLList(LLPtr ListStart)
{
   LLPtr Walker;
   
   Walker = ListStart;
   while (Walker != NULL) {
      printf("%1.2f --> ", Walker->data);
      Walker = Walker->next;
   }
   printf("(NULL)\n");
}

What to turn in

Turn in a hardcopy of the final program with the output given when you run it.