// File: list6.C // // A C++ implementation of linked-lists, using C++ reference parameters // and other C++ features #include #include #include #include "list6.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() { next = NULL ; } // alternate constructor ListNode::ListNode(const ListItem& x) { x.copyto(item) ; // item passed by reference next = NULL ; } // destructor ListNode::~ListNode() { // do nothing, ListItem destructor was called } //====================================================================== // List member function implementations // default constructor List::List() { count = 0 ; last = &header ; } // destructor List::~List() { ListNode *current, *temp ; // Iterate through the list, deleting each ListNode current = header.next ; while (current != NULL) { temp = current ; current = current->next ; delete temp ; } } // Add item to the end of the list void List::Append(const ListItem& 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(const ListItem& 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(const ListItem& x) { ListNode *current ; current = header.next ; while(current != NULL) { if ( current->item.compare(x) == 0) return 1 ; current = current->next ; } return 0 ; } // Add list to the end of this one, second list becomes empty void List::Concatenate(List *L2) { if (this == L2) { fprintf(stderr, "Cannot concatenate list with itself!\n") ; exit(1) ; } count += L2->count ; last->next = L2->header.next ; if (last->next != NULL) { last = L2->last ; } // make L2 an empty list L2->header.next = NULL ; L2->last = &L2->header ; L2->count = 0 ; } // 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) { temp = new ListNode(copyfrom->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->item.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 ListItem *List::FirstItem() { if (count == 0) return NULL ; return header.next->item.copy() ; } // Return a copy of the last item on the list ListItem *List::LastItem() { if (count==0) return NULL ; return last->item.copy() ; } // Return copy of item at given position ListItem *List::ItemAt(position pos) { if (pos == NULL || pos->next == NULL) { return NULL ; } return pos->next->item.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(const ListItem &x) { ListNode *prev ; prev = &header ; while(prev->next != NULL) { if ( prev->next->item.compare(x) == 0) return prev ; prev = prev->next ; } return NULL ; }