#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;
}