Computer Science 1511
Computer Science I

Laboratory Assignment 15
Linked List
Due at the end of Lab (Optional, Friday Labs only)

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:

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
{
   int int_data;
   char char_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 4 for int_data 
      and 'N' for char_data and then 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 2 for int_data and 
      the value 'A' for char_data place it after the node that stores 4 for 
      int_data (so the list is sorted in descending order according to int_data) 
      and print out the list.
   */
   
 
 
   
   printf("\n");
   printf("Third insert operation\n");
   /*
      Now write code to create a node to store the value 8 for int_data and 
      the value 'X' for char_data and place it at the beginning of the list 
      (so the list is still sorted in descending order according to int_data) 
      and print out the list.
   */
   
   
   
   
   printf("\n");
   printf("First delete operation\n");
   /*
        Now write code to delete the node that contains the
        value 'N' for char_data 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 8 for int_data from the list and print out the list.
   */
   
  
   printf("\n"); 
   fflush(stdin);
   printf("Press return  to Finish\n");
   getchar(); 
   return 0;
}

void printLList(LLPtr ListStart)
{
   LLPtr Walker;
   
   Walker = ListStart;
   while (Walker != NULL) {
      printf("%3d", Walker->int_data);
      printf("%3c  -->", Walker->char_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.