/* File: list5.C A more modular implementation of a simple linked list ADT in C++ */ #include #include #include #include "list5.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() { itemp = NULL ; next = NULL ; } /* alternate constructor */ ListNode::ListNode(data x) { itemp = new ListItem(x) ; CrashOnNull(itemp, "could not make new ListItem") ; next = NULL ; } /* destructor */ ListNode::~ListNode() { delete itemp ; } /* 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) ; CrashOnNull(ptr, "could not make new ListNode") ; 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) ; CrashOnNull(ptr, "could not make new ListNode") ; 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 ( current->itemp->compare(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, *temp ; NewL = new List ; CrashOnNull(NewL, "could not create new list") ; NewL->count = count ; copyto = &NewL->header ; copyfrom = header.next ; while(copyfrom != NULL) { /* old version: temp = new ListNode(copyfrom->itemp->copy()) ; */ temp = new ListNode(copyfrom->itemp->item) ; CrashOnNull(temp, "could not create new list") ; copyto->next = temp ; 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) { current->itemp->print() ; 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() { if (count == 0) return NULL ; return header.next->itemp->copy() ; } /* Return a copy of the last item on the list */ data List::LastItem() { return last->itemp->copy() ; } /* Return copy of item at given position */ data List::ItemAt(position pos) { if (pos == NULL || pos->next == NULL) { return NULL ; } return pos->next->itemp->copy() ; } /* 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 ( prev->next->itemp->compare(x) == 0) return prev ; prev = prev->next ; } return NULL ; }