//-------------------------------------------------------------------- // // Laboratory 10 listrec.cs // // (Shell) Partial linked list implementation of the List ADT with // additional recursive linked list functions // //-------------------------------------------------------------------- #include #include "stacklnk.cpp" #include "listrec.h" using namespace std; //-------------------------------------------------------------------- // // Insert your singly linked list implementations (from Laboratory 7) // of the following functions: // // - The ListNode class constructor // // - The List class constructor, destructor, insert(), clear(), and // showstructure() functions. You may also need to add empty() // full(), and others. // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // Recursively implemented linked list functions used in the Prelab // Exercise // //-------------------------------------------------------------------- template < class DT > void List
:: write () const // Outputs the data in a list from beginning to end. Assumes that // objects of type DT can be output to the cout stream. { cout << "List : "; writeSub(head); cout << endl; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > void List
:: writeSub ( ListNode
*p ) const // Recursive partner of the write() function. Processes the sublist // that begins with the node pointed to by p. { if ( p != 0 ) { cout << p->data; // Output data writeSub(p->next); // Continue with next node } } //-------------------------------------------------------------------- template < class DT > void List
:: insertEnd ( const DT &newDataItem ) // Inserts newDataItem at the end of a list. Moves the cursor to // newDataItem. { insertEndSub(head,newDataItem); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > void List
:: insertEndSub ( ListNode
*&p, const DT &newDataItem ) // Recursive partner of the insertEnd() function. Processes the // sublist that begins with the node pointed to by p. { if ( p != 0 ) insertEndSub(p->next,newDataItem); // Continue searching for else // end of list { p = new ListNode
(newDataItem,0); // Insert new node cursor = p; // Move cursor } } //-------------------------------------------------------------------- template < class DT > void List
:: writeMirror () const // Outputs the data in a list from beginning to end and back // again. Assumes that objects of type DT can be output to the cout // stream. { cout << "Mirror : "; writeMirrorSub(head); cout << endl; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > void List
:: writeMirrorSub ( ListNode
*p ) const // Recursive partner of the writeMirror() function. Processes the // sublist that begins with the node pointed to by p. { if ( p != 0 ) { cout << p->data; // Output data (forward) writeMirrorSub(p->next); // Continue with next node cout << p->data; // Output data (backward) } } //-------------------------------------------------------------------- template < class DT > void List
:: reverse () // Reverses the order of the data items in a list. { reverseSub(0,head); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > void List
:: reverseSub ( ListNode
*p, ListNode
*nextP ) // Recursive partner of the reverse() function. Processes the sublist // that begins with the node pointed to by nextP. { if ( nextP != 0 ) { reverseSub(nextP,nextP->next); // Continue with next node nextP->next = p; // Reverse link } else head = p; // Move head to end of list } //-------------------------------------------------------------------- template < class DT > void List
:: deleteEnd () // Deletes the data at the end of a list. Moves the cursor to the // beginning of the list. { deleteEndSub(head); cursor = head; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > void List
:: deleteEndSub ( ListNode
*&p ) // Recursive partner of the deleteEnd() function. Processes the // sublist that begins with the node pointed to by p. { if ( p->next != 0 ) deleteEndSub(p->next); // Continue looking for the last node else { delete p; // Delete node p = 0; // Set p (link or head) to null } } //-------------------------------------------------------------------- template < class DT > int List
:: getLength () const // Returns the number of data items in a list. { return getLengthSub(head); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > int List
:: getLengthSub ( ListNode
*p ) const // Recursive partner of the length() function. Processes the sublist // that begins with the node pointed to by p. { int result; // Result returned if ( p == 0 ) result = 0; // End of list reached else result = ( lengthSub(p->next) + 1 ); // Number of nodes after // this one + 1 return result; } //-------------------------------------------------------------------- // // "Unknown" operations used in the Bridge Exercise // //-------------------------------------------------------------------- template < class DT > void List
:: unknown1 () const // Unknown function 1. { unknown1Sub(head); cout << endl; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > void List
:: unknown1Sub ( ListNode
*p ) const // Recursive partner of the unknown1() function. { if ( p != 0 ) { cout << p->data; if ( p->next != 0 ) { unknown1Sub(p->next->next); cout << p->next->data; } } } //-------------------------------------------------------------------- template < class DT > void List
:: unknown2 () // Unknown function 2. { unknown2Sub(head); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template < class DT > void List
:: unknown2Sub ( ListNode
*&p ) // Recursive partner of the unknown2() function. { ListNode
*q; if ( p != 0 && p->next != 0 ) { q = p; p = p->next; q->next = p->next; p->next = q; unknown2Sub(q->next); } }