The delete at start of list algorithm in Java
 

You must have seen this or a similar algorithm in CS171:

   /* ====================================================
      delete(h): delete the first elem from the list h
                 return new list
      ==================================================== */
   public static List delete (List h)
   {
      if ( h != null )
         return (h.next); // Return new list that starts at h.next
      else 
         // deleting from empty list returns an empty list
         return null;
   }
   

I will include this delete method in the last Java program to do inserts + deletions

Java program that performs insertions + deletions
 

class List  // I want to use 1 prgram file for this example
{
   int value;
   List next;
}

public class demo
{

   public static void main(String[] args)
   {
      List head = null;    // Empty list
      List p;

      for ( int i = 0; i < 10; i++ )
      {
         p = new List( );
         p.value = i;
         head = insert(head, p);       // Insert p
         print(head);
      }

      for ( int i = 0; i < 10; i++ )
      {
         head = delete(head);       // Delete first element
         print(head);
      }

   }

   /* =========================================
      insert(h, e): insert e at tail of list h
                    return new list
      ========================================= */
   public static List insert( List head, List e )
   {
      /* --------------------------------------------
          Base case: insert at the tail of an empty
         -------------------------------------------- */
      if ( head == null )
      {
         e.next = null;     // Mark e as the last list elem
         return(e);         // e is the first list elem !
      }
      else
      {
         /* ===========================================================
            Solve the problem USING the solution of a smaller problem
            =========================================================== */
         head.next = insert( head.next, e ); // Link directly to helpSol

         return head;             // Return MY solution
      }
   } 


   /* ====================================================
      delete(h): delete the first elem from the list h
                 return new list
      ==================================================== */
   public static List delete (List h)
   {
      if ( h != null )
         return (h.next); // Return new list that starts at h.next
      else 
         // deleting from empty list returns an empty list
         return null;
   }

   // Print the list
   public static void print(List h)
   {
      while (h != null)
      {
         System.out.printf("%d ", h.value);
         h = h.next;
      }
      System.out.printf("\n");
   }
}
   

The delete at start of list algorithm in C
 

I will show you the how to translate the Java method in class:

   /* ====================================================
      delete(h): delete the first elem from the list h
                 return new list
      ==================================================== */
   struct List *delete (struct List *h)
   {
      if ( h != NULL )
         return (h->next); // Return new list that starts at h.next
      else 
         // deleting from empty list returns an empty list
         return NULL;
   }
   

I will include this delete method in the last C program to do inserts + deletions

C program that performs insertions + deletions
 

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

struct List       // This is the List class definition in C
{
   int          value;
   struct List *next;
};


struct List *insert( struct List *head, struct List *e );
struct List *delete (struct List *h);
void print(struct List *h);   // We must declare print to avoid compile error


void main(int argc, char *argv[])
{  
   struct List *head = NULL;   // Nul pointer NULL instead of null
   struct List *p;
   int c = 0;
   
   while (1)
   {
   for ( int i = 0; i < 10; i++ )
   {
      p = malloc( sizeof(struct List) );
      p->value = i;
      head = insert(head, p);       // Insert p in head
      print(head);
   }

   for ( int i = 0; i < 10; i++ )
   {
      head = delete(head);       // Insert p in head
      print(head);
   }

   printf("%d\n", ++c);
   }
}

struct List *insert( struct List *head, struct List *e )
{
   /* --------------------------------------------
       Base case: insert at the tail of an empty
      -------------------------------------------- */
   if ( head == NULL )
   {
      e->next = NULL;   // Mark e as the last list elem
      return(e);         // e is the first list elem !
   }
   else
   {
      /* ===========================================================
         Solve the problem USING the solution of a smaller problem
         =========================================================== */
      head->next = insert( head->next, e ); // Link directly to helpSol

      return head;             // Return MY solution
   }
}

/* ====================================================
   delete(h): delete the first elem from the list h
              return new list
   ==================================================== */
struct List *delete (struct List *h)
{
   if ( h != NULL )
      return (h->next); // Return new list that starts at h.next
   else
      // deleting from empty list returns an empty list
      return NULL;
}

// Print the list
void print(struct List *h)
{
   while (h != NULL)
   {
      printf("%d ", h->value);
      h = h->next;
   }
   printf("\n");
}
   

Difference between C and Java
 

  • The Java runtime support system has a built-in garbage collector subsystem that re-claim (= free up) "garbage" (= unaccessible objects)

  • The C runtime system does not have a run time garbage collection mechanism !!!

    Re-run the demo with:

        (ulimit -v 50000;  a.out > err)       

  • Result:

      • The C program will crash (out-of-memory error) !!!       

        (ulimit -v 50000 reduces the available memory)

Where did we generate garbage inside the delete( ) function ?
 

The first list element is "considered" as deleted:

   /* ====================================================
      delete(h): delete the first elem from the list h
                 return new list
      ==================================================== */
   struct List *delete (struct List *h)
   {
      if ( h != NULL )
      {  // Delete the 1st list element  
         // by returning the 2nd element 
	 // as "head"                    
         return (h->next);
      else 
         // deleting from empty list returns an empty list
         return NULL;
   }
   

You must explicitly de-allocate memory obtained using malloc( ) in C !!!

De-allocating "objects" using the C library function free( )

  • Dynamically allocated variables created by using:

         p = malloc( ... );            
      

    that are no longer accessible (i.e., becomes garbage) must be de-allocated using:

         free( p ) ;            
      

  • Caveat:

      • The free(p) call may updates some of the allocated memory cells that is being de-allocated.

How to de-allocate variables created by malloc( )
 

The original delete( ) function:

   /* ====================================================
      delete(h): delete the first elem from the list h
                 return new list
      ==================================================== */
   struct List *delete (struct List *h)
   {
      if ( h != NULL )
      { 
 


         return (h->next);
      }
      else 
         // deleting from empty list returns an empty list
         return NULL;
   }
   

How to de-allocate variables created by malloc( )
 

We must explicitly free(h) when we delete the 1st list element:

   /* ====================================================
      delete(h): delete the first elem from the list h
                 return new list
      ==================================================== */
   struct List *delete (struct List *h)
   {
      if ( h != NULL )
      { 


         free(h); // Caveat: free(h) may modify h->next ! 
         return (h->next);
      }
      else 
         // deleting from empty list returns an empty list
         return NULL;
   }
   

How to de-allocate variables created by malloc( )
 

We must explicitly free(h) when we delete the 1st list element:

   /* ====================================================
      delete(h): delete the first elem from the list h
                 return new list
      ==================================================== */
   struct List *delete (struct List *h)
   {
      if ( h != NULL )
      { 
         struct List *retVal = h->next; // Save return value 

         free(h); // Caveat: free(h) may modify h->next ! 
         return (retVal);
      }
      else 
         // deleting from empty list returns an empty list
         return NULL;
   }