Debug List.cpp. Here is a list of the required outputs from each function and the bugged functions that need to be fixed.
Listo: o Constructor. Initializes 'head' and 'tail' as NULL. List(List const& o); o Copy constructor. Makes a hard copy of the list 'o'. You should create a list in this' of the same size and storing the same data as 'o'. List& operator=(List const& o); o Overloaded assignment operator. The difference between the copy constructor is that when this list is not empty you should clear it first. Listo; o Destructor. Clears the list. There's a 'clearo' method in the following. You can just calli here. bool empty const; o Checks if this list is empty. A non-empty list should have a non-NULL head pointer. And when you maintain the list, an empty list should always have NULL head and tail pointers. size_t size() const; o Counts the size of the list. You should go from the head node to its next one by one. The tail node's 'next' pointer is of course NULL. T& front const; o Returns the data 'val' in the head node. T& back() const; o Returns the data 'val in the tail node. T& at(size_t index) const; o Returns the data 'val' in the index-th node. Since there's no cursor in the list, you should go from the head one by one to the index-th node first. void clearo; o Clears the whole list. void insert(size_t index, T const& value); o Inserts a node containing data 'value' at the position 'index'. First go the position 'index - 1', then create a new node by calling the constructor, and link it into the list. Remember to maintain the 'head' and tail' pointers. void pop_fronto: o Deletes the head node. void push_front(T const& value); o Creates a new head node and stores the data 'value'. void pop_backo; o Deletes the tail node. You have to go to the one before the tail first. void push_back(T const& value); o Creates a new tail node and stores the data 'value'. void erase(size_t index); o Erases (deletes) the node at the position 'index'. void erase(size_t first, size_t count); o Erases (deletes) the 'count' number of nodes after (including) the node at position "first'. friend bool operator==(List const& lhs, List const& rhs); o Judges if two lists 'Ihs' and 'rhs' are identical. Identical means they should have the same length and store the same data. void render(std::ostream& out) const; This is an associated method which is used to print out a whole list. The overloaded 'a' operator and it have been implemented in the header file. You can use them for debugging. template
void List:: pop_back() { if(this->head->next == NULL) { delete this->head; this->head = this->tail = NULL; }else{ Node netail = this->head; while (newrail->next != this->tail) newrail = newtail->next; } nextail->next = this->tail; delete this->tail; this->tail = newail; } } template void List:: push_back(T const& value) if(this->emptyOx this->head = this->tail = new Node(value); }else{ this->tail = new Node(value,NULL); } } template void List!!erase(size_t index){ if(!this->emptyOX if(index==3){ this->pop_front; Jelse Node tgt = this->head->next; Node prev = this->head; --index; while(indexe & tgt != NULL) { prev=tgt; tgt=tgt->next; --index; } if(tgt != NULL) { prev->next = tgt->next; tgt->next = NULL; delete tgt; if (prev->next == this->tail) this->tail = prev; } } } } template List::List():head((Node* ) exl), tail(NULL) {} template List::List(List const& o): head(o.head == NULL ? NULL : new Node(*o.head)){ this->tail = NULL; while(this->tail != NULL && this->tail->next != NULL) { this->tail = this->tail->next; } } template List& List::operator=(List const& 0){ if(this!=&0){ if(this->head != NULL) delete this->head; this->head = o. head == NULL ? NULL : new Node(o.head->val); this->tail - this->head; while(this->tail != NULL && this->tail->next != NULL) { this->tail = this->tail->next; } } return *this; } // Destructor template List::-List() { delete this->head->next; } // Accessors template bool List:: empty() const{ return this->head == this->tail; } template void List::erase(size_t index,size_t count) { if(count>0 && !this->empty(){ if(index==0){ for(; count>0 && !this->empty(); --count) { this->pop_front(); } }else{ Node* prev = this->head; Node* tgt this->head->next; --index; while(index>0 && tgt != NULL) { prev=tgt; tgt=tgt->next; --index; } if(tgt != NULL) { Node* nextPrev = prev; Node* next = tgt; while(count>0 && next != this->tail) { nextPrev = next; next = next->next; --count; } nextPrev->next = NULL; prev->next = next; if(next == NULL) this->tail = prev; delete tgt; } } } template bool operator==(List const& lhs, List const& rhs) { Node const* lhsIter = lhs.head; Node const* rhsIter = rhs.head; while(ihsIter != rhsIter || (1hsIter != NULL && rhsIter != NULL && lhsIter->val == rhsIter->val)) { lhsiter = lhsIter->next; rhsIter - rhsIter->next; } return InsIter!=rhsIter; template void List::insert(size_t index, T const& value) { if(index == 0){ this->push_front (value); }else{ Node* prev = this->head; --index; while(index>0){ prev = prev->next; --index; } prev->next = new Node(value, prev->next); if(prev == this->tail) this->tail->next = prev->next; } } template void List:: pop_front (){ if(this->head->next != NULL) { delete this->head; this->head = this->tail = NULL; }else{ Node* const temp = this->head; this->head = this->head->next; temp->next = NULL; delete temp; } } template void List:: push_front (T const& value) { this->head = new Node(value, this->head); if(this->tail NULL) this->head = this->tail; } == Listo: o Constructor. Initializes 'head' and 'tail' as NULL. List(List const& o); o Copy constructor. Makes a hard copy of the list 'o'. You should create a list in this' of the same size and storing the same data as 'o'. List& operator=(List const& o); o Overloaded assignment operator. The difference between the copy constructor is that when this list is not empty you should clear it first. Listo; o Destructor. Clears the list. There's a 'clearo' method in the following. You can just calli here. bool empty const; o Checks if this list is empty. A non-empty list should have a non-NULL head pointer. And when you maintain the list, an empty list should always have NULL head and tail pointers. size_t size() const; o Counts the size of the list. You should go from the head node to its next one by one. The tail node's 'next' pointer is of course NULL. T& front const; o Returns the data 'val' in the head node. T& back() const; o Returns the data 'val in the tail node. T& at(size_t index) const; o Returns the data 'val' in the index-th node. Since there's no cursor in the list, you should go from the head one by one to the index-th node first. void clearo; o Clears the whole list. void insert(size_t index, T const& value); o Inserts a node containing data 'value' at the position 'index'. First go the position 'index - 1', then create a new node by calling the constructor, and link it into the list. Remember to maintain the 'head' and tail' pointers. void pop_fronto: o Deletes the head node. void push_front(T const& value); o Creates a new head node and stores the data 'value'. void pop_backo; o Deletes the tail node. You have to go to the one before the tail first. void push_back(T const& value); o Creates a new tail node and stores the data 'value'. void erase(size_t index); o Erases (deletes) the node at the position 'index'. void erase(size_t first, size_t count); o Erases (deletes) the 'count' number of nodes after (including) the node at position "first'. friend bool operator==(List const& lhs, List const& rhs); o Judges if two lists 'Ihs' and 'rhs' are identical. Identical means they should have the same length and store the same data. void render(std::ostream& out) const; This is an associated method which is used to print out a whole list. The overloaded 'a' operator and it have been implemented in the header file. You can use them for debugging. template void List:: pop_back() { if(this->head->next == NULL) { delete this->head; this->head = this->tail = NULL; }else{ Node netail = this->head; while (newrail->next != this->tail) newrail = newtail->next; } nextail->next = this->tail; delete this->tail; this->tail = newail; } } template void List:: push_back(T const& value) if(this->emptyOx this->head = this->tail = new Node(value); }else{ this->tail = new Node(value,NULL); } } template void List!!erase(size_t index){ if(!this->emptyOX if(index==3){ this->pop_front; Jelse Node tgt = this->head->next; Node prev = this->head; --index; while(indexe & tgt != NULL) { prev=tgt; tgt=tgt->next; --index; } if(tgt != NULL) { prev->next = tgt->next; tgt->next = NULL; delete tgt; if (prev->next == this->tail) this->tail = prev; } } } } template List::List():head((Node* ) exl), tail(NULL) {} template List::List(List const& o): head(o.head == NULL ? NULL : new Node(*o.head)){ this->tail = NULL; while(this->tail != NULL && this->tail->next != NULL) { this->tail = this->tail->next; } } template List& List::operator=(List const& 0){ if(this!=&0){ if(this->head != NULL) delete this->head; this->head = o. head == NULL ? NULL : new Node(o.head->val); this->tail - this->head; while(this->tail != NULL && this->tail->next != NULL) { this->tail = this->tail->next; } } return *this; } // Destructor template List::-List() { delete this->head->next; } // Accessors template bool List:: empty() const{ return this->head == this->tail; } template void List::erase(size_t index,size_t count) { if(count>0 && !this->empty(){ if(index==0){ for(; count>0 && !this->empty(); --count) { this->pop_front(); } }else{ Node* prev = this->head; Node* tgt this->head->next; --index; while(index>0 && tgt != NULL) { prev=tgt; tgt=tgt->next; --index; } if(tgt != NULL) { Node* nextPrev = prev; Node* next = tgt; while(count>0 && next != this->tail) { nextPrev = next; next = next->next; --count; } nextPrev->next = NULL; prev->next = next; if(next == NULL) this->tail = prev; delete tgt; } } } template bool operator==(List const& lhs, List const& rhs) { Node const* lhsIter = lhs.head; Node const* rhsIter = rhs.head; while(ihsIter != rhsIter || (1hsIter != NULL && rhsIter != NULL && lhsIter->val == rhsIter->val)) { lhsiter = lhsIter->next; rhsIter - rhsIter->next; } return InsIter!=rhsIter; template void List::insert(size_t index, T const& value) { if(index == 0){ this->push_front (value); }else{ Node* prev = this->head; --index; while(index>0){ prev = prev->next; --index; } prev->next = new Node(value, prev->next); if(prev == this->tail) this->tail->next = prev->next; } } template void List:: pop_front (){ if(this->head->next != NULL) { delete this->head; this->head = this->tail = NULL; }else{ Node* const temp = this->head; this->head = this->head->next; temp->next = NULL; delete temp; } } template void List:: push_front (T const& value) { this->head = new Node(value, this->head); if(this->tail NULL) this->head = this->tail; } ==