280 likes | 531 Vues
Linked List. Chapter 17 Linked List as Objects. Linked List Design. We completed the basic operations in a linked list (Part A): Traverse the list Search for an item Insert an item Delete an item The last topic in the course is to implement linked list as objects. Where are we?.
E N D
Linked List Chapter 17 Linked List as Objects COMP103 - Linked Lists (Part B)
Linked List Design • We completed the basic operations in a linked list (Part A): • Traverse the list • Search for an item • Insert an item • Delete an item • The last topic in the course is to implement linked list as objects. COMP103 - Linked Lists (Part B)
Where are we? • So far, we have not treated linked list as an object. • We have not applied the principle of Abstract Data Type. • It is declared as struct type, therefore, the main program CAN access directly the fields in a NODE, such as data and link. • This creates problems when we • change the implementation of the NODE • don’t want to release the internal structure of NODE for security reasons COMP103 - Linked Lists (Part B)
Linked List Design // Node Constructor Node :: Node (int dataIn) { data = dataIn; link = NULL; } Node declared as a class: • 2 private members: • Data (relevant information) • link (pointer to the next Node) • Private constructor • Friend class List(to create and access a node) class Node { private: int data; Node* link; friend class List; Node (int); // constructor }; // class Node COMP103 - Linked Lists (Part B)
Friend class List as object 2 public functions Also keeps the 3 required pointers, as private variables addToList deleteFromList COMP103 - Linked Lists (Part B)
Class Definition of List class List { private: Node* pHead; Node* pPre; // predecessor Node* pCur; // current position in list bool addNode(int item); void deleteNode (); bool searchList (int argument); public: List (); // constructor ~List (); // destructor int addToList (int dataIn); bool deleteFromList (int key); }; COMP103 - Linked Lists (Part B)
addToList(public function) // Return 0 successful add // Return 1 item already in the list // Return 2 dynamic memory is full int List::addToList(int item) { int success; success = 0; // Default is successful if (searchList(item) == true) success = 1; // Found duplicate data else if (addNode(item) == false) success = 2; // Memory overflow return success; } • Calls 2 private functions: • searchList • addNode COMP103 - Linked Lists (Part B)
searchList(private function) bool List::searchList(int target) { bool found; pPre = NULL; pCur = pHead; // Search until target <= list data while (pCur && target > pCur->data) { pPre = pCur; pCur = pCur->link; } // Determine if target found if (pCur && target == pCur->data) found = true; else found = false; return found; } COMP103 - Linked Lists (Part B)
addNode(private function) bool List::addNode(int item) { Node* pNew; pNew = new Node(item); if (!pNew)return false; // memory overflow if (pPre == NULL){ // Add before first node or to empty list pNew->link = pHead; pHead = pNew; } else { // Add in the middle or at the end pNew->link = pPre->link; pPre->link = pNew; } return true; } COMP103 - Linked Lists (Part B)
deleteFromList(public function) bool List::deleteFromList(int key) { if (searchList(key)) { deleteNode(); return true; // found } else return false; // not found } • Calls 2 private functions: • searchList • deleteNode COMP103 - Linked Lists (Part B)
deleteNode(private function) void List::deleteNode() { if (pPre == NULL) pHead = pCur->link; // first node is deleted else pPre->link = pCur->link; // node at other location is deleted delete (pCur); return; } COMP103 - Linked Lists (Part B)
List constructor (default) When a new list is constructed, we must setpHead = NULL, because the list is initially empty. pPreandpCurmust also beNULL, since there is no node to point to. List::List() { pHead = NULL; pPre = NULL; pCur = NULL; } COMP103 - Linked Lists (Part B)
List destructor When a list is destroyed, we must delete all the nodes. To do this, we traverse the list and we delete the nodes one by one. List::~List() { Node *pDelete; Node *pTemp; pDelete = pHead; // while there are more nodes while (pDelete!=NULL) { pTemp = pDelete->link; delete pDelete; // delete the current node pDelete = pTemp; // go to the next node } } COMP103 - Linked Lists (Part B)
Recall the declarations of Node and List class List { private: Node* pHead; Node* pPre; // predecessor Node* pCur; // current position in list bool addNode(int item); void deleteNode (); bool searchList (int argument); public: List (); // constructor ~List (); // destructor int addToList (int dataIn); bool deleteFromList (int key); }; class Node { private: int data; Node* link; friend class List; Node (int); }; // class Node COMP103 - Linked Lists (Part B)
Problem!! • The data structure is in the node class, • Inside the List we do not know and cannot access the data in the node. • Outside the node, applications cannot access the pHead, pPre, pCur, etc. How can we traverse the item in the List from a program? COMP103 - Linked Lists (Part B)
Solution Another ADT (class) ListIterator enables one to manipulate a List object. • We can “use” ListIterator to perform the following functions: • Set the manipulation to start at the first item of the list: • functionreset • Advance to the next node in the list: • functionoperator++ • Determine whether the current node is valid or not: • functionoperator! • Access the content of the current node: • functionoperator* COMP103 - Linked Lists (Part B)
Iterator, List & Node COMP103 - Linked Lists (Part B)
ListIterator Class Definition class ListIterator { private: Node *pWalker; public: // set pWalker to the first node void reset(List &pList); // returns data in the current node int operator*(); // check whether pWalker points to a valid node bool operator!(); // advance to next node Node* operator++(int); }; COMP103 - Linked Lists (Part B)
Access to private data class Node { … // add this declaration friend class ListIterator; … }; class List { … // add this declaration friend class ListIterator; … }; • ListIterator must access the private members of Node and List • Therefore, ListIterator must be a friend of both Node and List COMP103 - Linked Lists (Part B)
reset and operator! main() { List list; ListIterator listWalker; listWalker.reset(list) … // add items to list while (!listWalker) { … } } // sets current pointer to header void ListIterator :: reset (List& list) { pWalker = list.pHead; } // checks whether pointer is valid bool ListIterator :: operator! () { return pWalker != NULL; } This statement will become false when we reach the end of the list COMP103 - Linked Lists (Part B)
operator++() main() { List list; ListIterator listWalker; listWalker.reset(list) … // add items to list while (!listWalker) { … listWalker++; } } // advance to the next node Node* ListIterator :: operator++ (int) { if (pWalker) pWalker = pWalker->link; return pWalker; } The syntax operator++(int) is used to denote the postfix operator: listWalker++ If you use operator++(void) instead, you declare a prefix operator: ++listWalker Will return to this later!! COMP103 - Linked Lists (Part B)
operator*() main() { List list; ListIterator listWalker; listWalker.reset(list) … // add items to list while (!listWalker) { … cout << *listWalker; listWalker++; } } // returns data in the current node int ListIterator :: operator* () { if (!pWalker) { cout << "Invalid list reference\n"; exit (105); } else return pWalker->data; } COMP103 - Linked Lists (Part B)
Example: calculate average const int LIST_SIZE = 100; // Prototype Declarations void buildList(List &list); void printAvrgList(List &list); void printList(List &list); void main() { List list; buildList(list); printList(list); printAvrgList(list); } COMP103 - Linked Lists (Part B)
buildList(List &list) void buildList (List &list) { int datum, result; int i; for (i = 0; i < LIST_SIZE; i++) { cout << “input integer: “ << endl; cin >> datum; // input integer result = list.addToList (datum); if (result == 1) cout << "Duplicate data: " << datum << endl; else if (result == 2) cout << "\a\aERR 200: Memory Overflow\n"; } // end for } COMP103 - Linked Lists (Part B)
printList(List &list) void printList(List& list) { ListIterator listWalker; listWalker.reset(list); cout << “ The list is “<< endl; while (!listWalker) { cout << “data: “ << *listWalker << endl; listWalker++; } } COMP103 - Linked Lists (Part B)
printAvrgList(List &list) void printAvrgList (List& list) { int count = 0, sum = 0; float avrg; ListIterator listWalker; listWalker.reset(list); // set to header while (!listWalker) { sum += *listWalker; // sum = sum + data count++; // increment count listWalker++;// next node } if (count) avrg = (float) sum / count; else avrg = 0; cout << "\nTotal value: " << sum << "\n for " << count << " items.“ << "\nAverage is: " << avrg << endl; } COMP103 - Linked Lists (Part B)
The End COMP103 - Linked Lists (Part B)