1 / 57

Class 7

Class 7. Objectives. Differentiate between a static data structure and a dynamic data structure Create a dynamic data structure class using a linked list Describe how nodes are inserted and remove from a linked list. What is a linked list?.

dacia
Download Presentation

Class 7

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Class 7

  2. Objectives • Differentiate between a static data structure and a dynamic data structure • Create a dynamic data structure class using a linked list • Describe how nodes are inserted and remove from a linked list

  3. What is a linked list? • It is a collection of items created dynamically (at run-time) • Each item (node) is connected through a pointer • Linked lists are differentiated from an array which is created at compile time and is accessed via a subscript • The elements in a linked list are accessed via a pointer • A linked list node consists of a data portion and at least one pointer

  4. 25 Null 3. The programmer can then place data in the data portion of the node 4. The programmer should then set nextPtr to Null or connect it to another node if there is one Data nextPtr At run-time • A node (consisting of a data portion and a pointer) is created • It’s address is placed in a pointer firstptr

  5. Another node (consisting of a data portion and a pointer) is created • It’s address is placed in a pointer Existing node Data nextPtr 25 Null currentPtr 45 firstptr 3. The programmer can then place data in the data portion of the node

  6. The two nodes need to be connected • Should the node with the 45 be placed before or after the node with the 25? Data nextPtr 25 Null currentPtr 45 firstptr

  7. Placing it to the right would be processing the linked list as a queue • To the left would be a stack Data nextPtr 25 Null currentPtr 45 firstptr

  8. To add the new node to the end of the linked list means connecting the pointer in the node with the 25 to the beginning of the node with the 45 and setting the node with the 45 pointer to Null Data nextPtr 25 Null currentPtr 45 firstptr

  9. To add the new node to the end of the linked list means connecting the pointer in the node with the 25 to the beginning of the node with the 45 and setting the node with the 45 pointer to Null Data nextPtr 25 currentPtr 45 Null firstptr

  10. To add the new node to the beginning of the linked list means setting the “45” node’s nextPtr to point to the “25” node and then setting firstptr the value of currentPtr so that it points to the “45” node and then Data nextPtr 25 Null currentPtr 45 firstptr

  11. Creating a class containing a node structure and methods for processing a linked list

  12. // Specification file for the List class #ifndef NUMBERLIST_H #define NUMBERLIST_H typedef int ListItemType; class List { private: struct ListNode { ListItemType value; struct ListNode *next; }; ListNode *head; // List head pointerint size; ListNode *find(int index) const;

  13. public: List() // Constructor List(const List & ) { head = NULL; size =0; } ~List(); // Destructor void appendNode(ListItemType); void insert(int , const ListItemType &); void remove(int index); void retrieve(int , const ListItemType &); bool isEmpty() const; int getLength() const; }; #endif

  14. List::List(const List& aList) : size(aList.size) { if (aList.head == NULL) head = NULL; // original list is empty else { // copy first node head = new ListNode; head->item = aList.head->item; // copy rest of list ListNode *newPtr = head; // new list pointer // newPtr points to last node in new list

  15. // origPtr points to nodes in original list for (ListNode *origPtr = aList.head->next; origPtr != NULL; origPtr = origPtr->next) { newPtr->next = new ListNode; newPtr = newPtr->next; newPtr->item = origPtr->item; } // end for newPtr->next = NULL; } // end if } // end copy constructor

  16. List::~List() { while (!isEmpty()) remove(1); } // end destructor bool List::isEmpty() const { return size == 0; } // end isEmpty int List::getLength() const { return size; } // end getLength

  17. List::ListNode *List::find(int index) const { if ( (index < 1) || (index > getLength()) ) return NULL; else // count from the beginning of the list. { ListNode *cur = head; for (int skip = 1; skip < index; ++skip) cur = cur->next; return cur; } // end if } // end find

  18. void List::retrieve(int index, ListItemType& dataItem) const { if ( (index < 1) || (index > getLength()) ) cout << "ListIndexOutOfRangeException : retrieve index out of range"); else { // get pointer to node, then data in node ListNode *cur = find(index); dataItem = cur->item; } // end if } // end

  19. void List::insert(int index, const ListItemType& newItem) { int newLength = getLength() + 1; if ( (index < 1) || (index > newLength) ) cout << "ListIndexOutOfRangeException: insert index out of range"); else { ListNode *newPtr = new ListNode; size = newLength; newPtr->item = newItem; // attach new node to list if (index == 1) { // insert new node at beginning of list newPtr->next = head; head = newPtr; }

  20. else { ListNode *prev = find(index-1); // insert new node after node // to which prev points newPtr->next = prev->next; prev->next = newPtr; } // end if } // end if } // end insert

  21. void List::remove(int index) { ListNode *cur; if ( (index < 1) || (index > getLength()) ) cout << "ListIndexOutOfRangeException: remove index out of range"); else { --size; if (index == 1) { // delete the first node from the list cur = head; // save pointer to node head = head->next; }

  22. else { ListNode *prev = find(index - 1); // delete the node after the node to which prev points cur = prev->next; // save pointer to node prev->next = cur->next; } // end if // return node to system cur->next = NULL; delete cur; cur = NULL; } // end if } // end remove

  23. // Saves a linked list's data in a text file of // integers; head points to the linked list. // fileName is a string that names an external text // file to be created ofstream outFile(fileName); // traverse the list to the end, writing each item for (Node *cur = head; cur != NULL; cur = cur->next) outFile << cur->item << endl; outFile.close(); // Assertion: The text file contains the linked // list's data in its original order.

  24. Templating a class for a linked list

  25. // Specification file for the LinkedList class #ifndef LINKEDLIST_H #define LINKEDLIST_H template <class T> class LinkedList { private: // Declare a structure for the list struct ListNode { T value; struct ListNode *next; }; ListNode *head; // List head pointer

  26. public: LinkedList() // Constructor { head = NULL; } ~LinkedList(); // Destructor void appendNode(T); void insertNode(T); void deleteNode(T); void displayList(); }; #endif

  27. // Implementation file for the LinkedList class #include <iostream> // For cout and NULL #include “LinkedList.h" using namespace std;template <class T> void LinkedList<T>::appendNode(T num) { ListNode *newNode, *nodePtr; // Allocate a new node & store num newNode = new ListNode; newNode->value = num; newNode->next = NULL;

  28. // If there are no nodes in the list // make newNode the first node if (!head) head = newNode; else // Otherwise, insert newNode at end { // Initialize nodePtr to head of list nodePtr = head; // Find the last node in the list while (nodePtr->next) nodePtr = nodePtr->next; // Insert newNode as the last node nodePtr->next = newNode; } }

  29. template <class T>void LinkedList<T>::displayList() { ListNode *nodePtr; nodePtr = head; while (nodePtr) { cout << nodePtr->value << endl; nodePtr = nodePtr->next; } }

  30. template <class T>void LinkedList<T>::insertNode(T num) { ListNode *newNode, *nodePtr, *previousNode = NULL; // Allocate a new node & store num newNode = new ListNode; newNode->value = num; // If there are no nodes in the list // make newNode the first node if (!head) { head = newNode; newNode->next = NULL; } else

  31. { nodePtr = head; previousNode = NULL; while (nodePtr != NULL && nodePtr->value < num) { previousNode = nodePtr; nodePtr = nodePtr->next; } if (previousNode == NULL) { head = newNode; newNode->next = nodePtr; }

  32. else // Otherwise, insert it after the prev. node. { previousNode->next = newNode; newNode->next = nodePtr; } } } template <class T> void LinkedList<T>::deleteNode(T num) { ListNode *nodePtr, *previousNode; // If the list is empty, do nothing. if (!head) return;

  33. // Determine if the first node is the one. if (head->value == num) { nodePtr = head->next; delete head; head = nodePtr; } else {

  34. // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is // not equal to num. while (nodePtr != NULL && nodePtr->value != num) { previousNode = nodePtr; nodePtr = nodePtr->next; }

  35. // If nodePtr is not at the end of the list, // link the previous node to the node after // nodePtr, then delete nodePtr. if (nodePtr) { previousNode->next = nodePtr->next; delete nodePtr; } } }

  36. NumberList::~NumberList() { ListNode *nodePtr, *nextNode; nodePtr = head; while (nodePtr != NULL) { nextNode = nodePtr->next; delete nodePtr; nodePtr = nextNode; } }

  37. Creating a ListNode class instead of using a structure of type ListNode

  38. template <class T> class List; // a forward decl. template<class T>class ListNode { friend class List< T >; // make List a friend public: ListNode( const T & ); // constructor T getData() const; // return data in the node private: T data; // data ListNode< T > *nextPtr; // next node in the list };

  39. // Constructor template<classT> ListNode< T >::ListNode( const T &info ) : data( info ), nextPtr( 0 ) { } // Return a copy of the data in the node template< class T > T ListNode< T >::getData() const { return data; } #endif

  40. Create a List class to do the following • Create a new node • Insert a node into the list, front and back • Delete a node from the list, front and back • Display the contents of the data portion of each node, until the end of the list

  41. template< class T >class List {public: List(); // constructor ~List(); // destructor void insertAtFront( const T & ); void insertAtBack( const T & ); bool removeFromFront( T & ); bool removeFromBack( T & ); bool isEmpty() const; void print() const;private: ListNode< T > *firstPtr; // pointer to first node ListNode< T > *lastPtr; // pointer to last node

  42. // PrivateUtility function to allocate a new node ListNode< T > *getNewNode( const T & ); };

  43. Implementation of List Class

  44. // Default constructor template< class T >List< T >::List() : firstPtr( 0 ), lastPtr( 0 ) { }

  45. // Is the List empty? template< class T > bool List< T >::isEmpty() const { return firstPtr == 0; } // Return a pointer to a newly allocated node template< class T > ListNode< T > *List< T >:: getNewNode( const T &value ) { ListNode< T > *ptr = new ListNode< T >( value ); assert( ptr != 0 ); return ptr; }

  46. // Display the contents of the Listtemplate< class NODETYPE >void List< T >::print() const { if ( isEmpty() ) {cout << "The list is empty\n\n"; return; } ListNode< T > *currentPtr = firstPtr;cout << "The list is: "; while ( currentPtr != 0 ) { cout << currentPtr->data << ‘ ‘; currentPtr = currentPtr->nextPtr; } }

  47. // Destructor// FOR THE WHOLE LINKED LISTtemplate< class T >List< T >::~List() { if ( !isEmpty() ) { // List is not empty cout << "Destroying nodes ...\n"; ListNode< T > *currentPtr = firstPtr, *tempPtr; while ( currentPtr != 0 ) { tempPtr = currentPtr; cout << tempPtr->data << '\n'; currentPtr = currentPtr->nextPtr; delete tempPtr; } } cout << "All nodes destroyed\n\n"; }

  48. Inserting into a linked list

  49. // Insert a node at the front of the listtemplate< class T >void List< T >::insertAtFront( const T &value ) {ListNode< T > *newPtr = getNewNode( value ); if ( isEmpty() ) // List is empty firstPtr = lastPtr = newPtr; else { // List is not empty newPtr->nextPtr = firstPtr; firstPtr = newPtr; } }

  50. // Insert a node at the back of the listtemplate< class T > void List< T >::insertAtBack( const T &value ) { ListNode< T > *newPtr = getNewNode( value ); if ( isEmpty() ) // List is empty firstPtr = lastPtr = newPtr; else { // List is not empty lastPtr->nextPtr = newPtr; lastPtr = newPtr; }}

More Related