-=LINK LISTS ADT=-

Well, I know when the term "link list" comes up in a C++ class or anywhere else, we get scared...I know I did. But lists aren't really all that bad. Once you get the hang of it, you'll be able to code up a list ADT without even thinking about it.

I'm going to try and explain how lists work, both a single and doubley linked list. I'm pretty sure after you read this, you'll have a pretty good idea of how they work and how to code one up real fast.

-=Singly Linked Lists=-

A singly linked list is just a series of nodes that are connected together by a pointer. Lists in C++ are always coded up in the form of a class, two classes actually. One calss for the list itself and one class for each node that the list.

The list of course, will contain all the member functions that your ADT class will do to the list. The most common member functions for a singly linked list are basically to append a node to the list, to delete the first node, all of which depend on the tasks your ADT will do (i.e. stack lists, queue list, etc.). Your node on the other hand only contains the pointer that points to the next node, and the data feild, which can be of any data type. Also, the node has to be made a friend of the list class in order for all the member functions to have access to the pointer and data fields.

Here is a little pesudo-code to help you get started:

class list public member functions (i.e. constructor, destructor, append, etc.) private *firstpointer (points to the beginning of the list) *lastpointer (optional: points to the end of the list) class node make this class a friend of class list private data feild *nextpointer (points to the next node)

Now you might be asking how do I create the nodes and how do I work with the list itself. This is really not hard at all. The first thing you need to do is to initalize your first pointer to point to NULL before you append or do anything, this mainly goes in your constructor.


	first   last
            \   /
             \ /
              -> NULL


Now the fun part...the member functions.

To add a new node to a list, you have to first create a new node with a poitner pointing to it, something in the lines of this:

*temp = new node (b in the figure below)

this creates a new node, but it's not yet connected to the list yet...it's just floating out someplace in memory. So how do you append? Using the indirect operator (->), you just have to do a few simple steps to append this to the begging or the end of the node (but to append at the end, it would be a whole lot easier and faster to use a last poitner as well).

If the list eas empty, that is (a) first == NULL or last == NULL, all you have to do is set (c) first = last =temp. that's basically it, but you always have to set the next feild of the node to NULL if that node is the first one in the list. You'll have many problems if you leave it poiting to some arbitrary place. So this is inserting at the front of an empty list.


     a) Initalize the list pointer
 
	first	last
           \    /
            \  / 
             -> NULL      
                  
    

     b) Create the node

	   +------+--+
 temp----> | node |  |-->
           +------+--+
                 
  
     c) Insert the node in the list
		    
     first             last
       \               /
        \+------+--+ /
      -->| node |  |-->NULL     
     /   +------+--+
temp/

   

But what about a non-empty list you ask? Still, easy. Inserting to the beginning or end of the list is exactly like inserting into an empty list with one or two extra operations. Like before, you first have to create the new node (b). This time, you can't set first = temp becuase if you do, you basically lose the existing list because there is nothing pointing to it. So to inset the new node, you have to set the next poitner of the new node equal to first, temp->next = first (c). This links the node to the beginning of the list, even before first. Now you might be happy with that, but any member functions that iterates throught the list will always miss that and any other new nodes you insert becase it always starts iterating at the first node. So the next step is to set first = temp in order to make the new node the first one (d).


                                
      a) Initial list
                       
	 first                  
            \                   
             \   +------+--+       
              -> | node |  |-->NULL
                 +------+--+


      b)  create the new node           

		   +------+--+
 	 temp----> | node |  |-->
         	   +------+--+
                 
      
      c) Insert node into the list
                  
                              first
                                  \
                                   \   +------+--+
                                    -->| node |  |-->NULL
                      +------+--+  /   +------+--+
             temp---->| node |  |--
                      +------+--+

      d) point first pointer to the beginning of the list   
                                  
             first                     +------+--+
                \                   -->| node |  |-->NULL
                 \    +------+--+  /   +------+--+
             temp---->| node |  |--
                      +------+--+

This is basically how you append a node to the beginning of a list. The exact same goes for appending to the end of the list, the only difference is that instead of working with the first pointer, you have to deal with the last pointer.



                                      
      a) End of the list
	                  last        
	                    /         
                           /          
                 +------+--+          
                 | node |  |-->NULL
                 +------+--+


                    
      b) Create the new node
		                           +--next pointer
       	                                   | 
	                         +------+--+  
                        temp---->| node |  |-->NULL
                                 +------+--+
              

      c) Set the last node's next pointer = to the new node        

 			last
                         /          
                        /                               
                 +------+--+                               
                 | node |  |----------                  
                 +------+--+          \    +------+--+
				  temp---->| node |  |-->NULL
                                           +------+--+

      d) Point the last pointer to the end of the list   

 			
                                   
                                          last              
                 +------+--+              /                  
                 | node |  |----------   /                
                 +------+--+          \ /  +------+--+
				  temp---->| node |  |-->NULL
                                           +------+--+          
      

That is basically how you append a node to the end of the list. You just have to make sure that the end of the list points to NULL or you might get unexpected results if you iterate throught the list and check if the last->next == NULL or not.

Deleting from a list is also very easy, but depends on which end you want to delete from. If you are working with a singly linked list and want to delete from the beginning of the list, it's very easy, but if you want to do delete from the end of the list, it becomes a bit more time consuming. This brings up to the subject of a doubly linked list.

-=Doubly Linked Lists=-

A doubly linked list is the exact same thing as a singly with just one more added pointer, a previous poitner that points to the node before the current one. Doubly linked lists are really good for constant operations (excluding printing the whole list or deleteing the whole list). As before, you have your list and node class with the one new pointer added in:


class list
  public
    member functions (i.e. constructor, destructor, append, etc.)

  private
     *firstpointer (points to the beginning of the list)
     *lastpointer (optional: points to the end of the list)

class node
   make this class a friend of class list
   
   private
     data feild
     *nextpointer (points to the next node)
     *previouspointer (points to the last node)

All operations are baisically the same for the doubly linked list as they are for the singly list, but all you have to do is keep track of where the previous poitner points too.

For example, to insert a new node in an empty list, you carry out the same steps as you would in a singly linked list and just set the previous pointer to NULL like so:


     a) Create the list             

	first		
           \         
	    \		
             ->NULL         


     b) Create the new node (notice the new previous pointer)

		        +------+--+
              temp----> |      |  | (next)
		    <---| node |  |-->
                 (prev) +------+--+
             

     
     c) Set first == to the new node and set the previous pointer = NULL

		    first
                       \
                        \   +------+--+
                         -->| node |  |-->NULL     
		    NULL<---|      |  |
                         /  +------+--+
                        / 
                       /
                    temp

You have to set the previous poitner to null for the first node in case you want to iterate backwards from the end, then you know where the beginning of the list is. Also, you could use the previous pointer to point to last->next to have a circular list.


		    first
                       \
                        \   +------+--+ (next)
                         -->| node |  |--     
		  (prev) ---|      |  |  \
                        /   +------+--+   \ 
                       |                   |
                       |                   |
                        -------------------

Inserting to an existing list is also very easy. For example, to insert at the end of a list, you just append the node the same way you did for a singly linked list with the exception that you have to set the previous pointer to point to last before you move the last pointer to point to the new node you created.



                                     
      a) The end of the list
              
			   last       
	                    /        
                           /         
                 +------+--+         
              <--| node |  |-->NULL  
                 +------+--+         

      
     b) Create the new node
                    
                                         +--next pointer
                                         | 
	                    +------+--+  |
                         <--| node |  |-->NULL
                            +------+--+
                           /
                        temp

     c) insert the new node at the end of the list       

 			last
                         /          
                        /                               
                 +------+--+   (next)                      
       more   <--| node |  |------------                  
         nodes   +------+--+ \          \  +------+--+
			      +----------- | node |  |-->NULL
                               (prev)      +------+--+

     d) move last to point to the new node

		            
                                    
                                                last    
                 +------+--+   (next)           /          
       more   <--| node |  |------------       /          
         nodes   +------+--+ \          \  +------+--+
			      +----------- | node |  |-->NULL
                               (prev)      +------+--+
              

Deleting from a list is also very easy, and in the case of the list above, trivial. First, you create a new pointer and point it to the end of the list. Then, in the case of the double link list, you move last to last->previous, and just delete the temp pointer you created. You also have to be sure to set the next pointer of the last node to null too.


    a) create the temp pointer to point to the node to delete 
       
                                                last    
                 +------+--+   (next)           /          
        more  <--| node |  |------------       /          
          nodes  +------+--+ \          \  +------+--+
			      +----------- | node |  |-->NULL
                               (prev)      +------+--+
                                              /
                                             /
                                           temp

    b) Move the last pointer to last->previous
                          
			last      
			 /
                        /                           
                 +------+--+   (next)                     
        more  <--| node |  |------------                 
          nodes  +------+--+ \          \  +------+--+
			      +----------- | node |  |-->NULL
                               (prev)      +------+--+
                                              /
                                             /
                                           temp


    c) Finaly delete temp and set next pointer of the last node to NULL


			last
                         /
			/     
                 +------+--+  
        more  <--| node |  |-->NULL
          nodes  +------+--+ 
			     
                             

Lists aren't very hard at all, trust me, I always had problems with them, and now I'm writing about them. I overcame them by just writing code down and drawing a picture. Pictures always help you visualize what you are doing, so it's good practice to draw them. I hope this little page helped in some way.



Written by: John Mikhail