/* File: list4.C Implementation of a simple linked list ADT in C++ */ #include #include #include #include "list4.h" /* Functions for this file only */ static void CrashOnNull(void *, char *) ; static void CrashOnNull(void *ptr, char *mesg) { if (ptr ==NULL) { fprintf(stderr, "CrashOnNull: %s\n", mesg) ; exit(1) ; } return ; } /* ListNode member function implementations */ /* default constructor */ ListNode::ListNode() { item = NULL ; next = NULL ; } /* alternate constructor */ ListNode::ListNode(data x) { if (x != NULL) { item = strdup(x) ; } else { item = NULL ; } next = NULL ; } /* destructor */ ListNode::~ListNode() { if (item != NULL) free(item) ; } /* List member function implementations */ /* default constructor */ List::List() { count = 0 ; last = &header ; } /* destructor */ List::~List() { ListNode *current, *temp ; current = header.next ; while (current != NULL) { temp = current ; current = current->next ; delete temp ; } } /* Add item to the end of the list */ void List::Append(data x) { ListNode *ptr ; ptr = new ListNode(x) ; last->next = ptr ; last = ptr ; count++ ; } /* Add item to the beginning of the list */ void List::Prepend(data x) { ListNode *ptr ; ptr = new ListNode(x) ; ptr->next = header.next ; header.next = ptr ; count++ ; if (ptr->next == NULL) last = ptr ; } /* Remove node at given position */ void List::Delete(position pos) { ListNode *temp ; /* Sanity check */ if (pos == NULL || pos->next == NULL) return ; temp = pos->next ; pos->next = pos->next->next ; delete temp ; count-- ; /* Check if we deleted the last node */ if (pos->next == NULL) last = pos ; } /* Item on the list? 0=No 1=Yes */ int List::IsMember(data x) { ListNode *current ; current = header.next ; while(current != NULL) { if ( strcmp(current->item, x) == 0) return 1 ; current = current->next ; } return 0 ; } /* Add list to the end of this one, second list destroyed */ void List::Concatenate(List *L2) { count += L2->count ; last->next = L2->header.next ; if (last->next != NULL) { last = L2->last ; } /* isolate L2 from old data */ L2->header.next = NULL ; L2->last = &L2->header ; L2->count = 0 ; delete L2 ; } /* Return copy of this list */ List *List::Duplicate() { List *NewL ; ListNode *copyto, *copyfrom ; NewL = new List ; CrashOnNull(NewL, "could not create new list") ; NewL->count = count ; copyto = &NewL->header ; copyfrom = header.next ; while(copyfrom != NULL) { copyto->next = new ListNode(copyfrom->item) ; copyto = copyto->next ; copyfrom = copyfrom->next ; } NewL->last = copyto ; return NewL ; } /* Print the contents of this list */ void List::Print() { ListNode *current ; current = header.next ; if (current == NULL) { printf("<>\n") ; return ; } printf("<") ; while (1) { printf("%s", current->item) ; current = current->next ; if (current == NULL) break ; printf(", ") ; } printf(">\n") ; } /* Return number of items in this list */ int List::Count() { return count ; } /* Return a copy of the first item on the list */ data List::FirstItem() { data x ; if (count == 0) return NULL ; x = strdup(header.next->item) ; CrashOnNull(x, "could not copy data item") ; return x ; } /* Return a copy of the last item on the list */ data List::LastItem() { data x ; x = strdup(last->item) ; CrashOnNull(x, "could not copy data item") ; return x ; } /* Return copy of item at given position */ data List::ItemAt(position pos) { data x ; if (pos == NULL || pos->next == NULL) { return NULL ; } x = strdup(pos->next->item) ; CrashOnNull(x, "could not copy data item") ; return x ; } /* Position of the first item */ position List::FirstPos() { return &header ; } /* Position after the given one */ position List::NextPos(position pos) { if (pos == NULL) return NULL ; return pos->next ; } /* Position of data on list. return NULL if no such node found.*/ position List::Locate(data x) { ListNode *prev ; prev = &header ; while(prev->next != NULL) { if ( strcmp(prev->next->item, x) == 0) return prev ; prev = prev->next ; } return NULL ; }