All pastes #2120614 Raw Edit

Untitled

public text v1 · immutable
#2120614 ·published 2012-02-22 03:14 UTC
rendered paste body
#include "ilist_destructive.h"
#include <stdlib.h>


// The ilist ADT is a pointer to this secret struct
struct ilist_ADT {
   struct ilist_ADT * rest;
   int first;
   int length;
};


// returns an empty ilist
ilist iempty(){
   return NULL;
}


// returns 1 if the ilist is empty, 0 if it is not
int iempty_huh(ilist il){
   if (il == iempty()) {
      return 1;
   }
   else return 0;
}


// reutrns the first element in an ilist
// ilist should not be empty
int ifirst(ilist il){
    return il->first;
}


// returns an ilist with a in added as the first element of the ilist
// references cease to be valid ilists
// does not promise not to mutate its arguments
ilist icons_destroy(int in, ilist il) {  
   // if the ilist is empty, create a new ADT node
   if (il == NULL) {
      ilist new_list = malloc(sizeof(struct ilist_ADT));
      new_list->rest = iempty();
      new_list->length = 1;
      new_list->first = in;
      return new_list;
   }
   
   // "duplicate" il values into a new node
   ilist il_dupe = malloc(sizeof(struct ilist_ADT));
   il_dupe->length = il->length;
   il_dupe->first = il->first;
   il_dupe->rest = il->rest;
   
   // link the nodes togher
   il->length = ilength(il) + 1;
   il->rest = il_dupe;
   il->first = in;
   return il;
}


// modifies il to remove the first element,
// and returns the modified ilist
// frees memory associated with the first element
ilist irest_destroy(ilist il){
   // set a temp to the rest of il
   ilist temp = il->rest;
   int length_temp = il->length;
   // if the il is empty
   if (temp == NULL) {
      free(il); return temp;
   }
   
   // move everything in temp to il1
   il->first = temp->first;
   il->length = length_temp - 1; 
   il->rest = temp->rest;
   free(temp);
   return il;
}


// returns a new copy of the ilist that continues to be a vild
// ilist with the same elemnts even when il is destroyed
ilist icopy(ilist il){
   if (il == iempty()) return iempty();
   int length_temp = il->length;
   
   ilist head = malloc(sizeof(struct ilist_ADT ));
   head ->first = il ->first;
   head ->rest = NULL;
   ilist lstend = head; 
   
   for (ilist a = il ->rest; a != NULL; a = a->rest) {
      ilist tmp = malloc(sizeof(struct ilist_ADT ));
      tmp ->first = a->first;
      tmp ->rest = NULL;
      lstend ->rest = tmp;
      lstend = tmp;
   }
   
   head->length = length_temp;
   return head;
}


// returns the length of an ilist
int ilength(ilist il){
   if (il == NULL) return 0;
   return il->length;
}


// free memory for entire ilist
void idelete(ilist il){
   while (il != NULL) { 
      ilist next = il->rest;
      free(il);
      il = next;
   }
}


// modifies il1 and il2 to form an ilist consisting of the
// elements from il1 followed by the elements from il2
// references to il1 and il2 cease to be valid ilists
ilist iappend_destroy(ilist il1, ilist il2){
   // special cases
   if (iempty_huh(il1) && iempty_huh(il2)) return iempty();
   if (il1 == NULL) return il2;
   if (il2 == NULL) return il1;
   // if they point to the same struct, make a new struct
   if (il1 == il2) il2 = icopy(il2);
   
   // remember length of il1, il2
   int il1_length = ilength(il1);
   int il2_length = ilength(il2);
   
   // creating temp il1
   ilist temp = il1;

   // finding last element in il1
   while(temp->rest != NULL) {
      temp = temp->rest; 
   }
   
   // linking final node to il2
   temp->rest = il2;
   il1->length = il1_length + il2_length;
   return il1;
}