Upcoming SlideShare
×

# Cfe2 ch13 final

675 views
588 views

Published on

0 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

• Be the first to like this

Views
Total views
675
On SlideShare
0
From Embeds
0
Number of Embeds
46
Actions
Shares
0
16
0
Likes
0
Embeds 0
No embeds

No notes for slide

### Cfe2 ch13 final

1. 1. Chapter Thirteen: Lists, Stacks, and Queues C++ for Everyone by Cay HorstmannSlides by Evan Gallagher Copyright © 2012 by John Wiley & Sons. All rights reserved
2. 2. Chapter Goals • To become familiar with the list, stack, and queue data types • To understand the implementation of linked lists • To understand the efficiency of vector and list operations C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
3. 3. Using Linked Lists Can we hope that the employees will be hired in order of their last names so that we will be putting them into the vector in the order we want? How else can the data be kept in the order we want it in the vector? (Insert an employee; sort; insert an employee; sort; insert an employee; sort;… No! Too much processing.) C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
4. 4. Using Linked Lists For each new employee, we could find the position in the vector where their data should be inserted and insert it. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
5. 5. Using Linked Lists For each new employee, we could find the position in the vector where their data should be inserted and insert it. But what about all the other records after this one? Won’t they need to be MOVED inside the vector? (yes) C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
8. 8. Using Linked Lists Rather than storing the data in a single block of memory, a linked list uses a different strategy. Each value is stored in its own memory block, together with the locations of the block “before” it and “after” it in the sequence. This memory block is traditionally called: a node. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
10. 10. Using Linked Lists Each node contains its data and a pointer to the previous node in the list . C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
11. 11. Using Linked Lists Each node contains its data and a pointer to the previous node in the list . C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
12. 12. Using Linked Lists Each node contains its data and a pointer to the previous node in the list and a pointer the next node in the list. . C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
13. 13. Using Linked Lists Each node contains its data and a pointer to the previous node in the list and a pointer the next node in the list. . C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
26. 26. Using Linked Lists Well, insertion and deletion are that easy. Where to do the insert or delete is the problem. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
27. 27. Using Linked Lists Try to delete the 5th element in a linked list. You would have to first do a linear search just to find the 5th element! This is called Sequential Access. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
28. 28. Using Linked Lists In a vector or an array, using the [ ], you can go directly to an element position. This is called Random Access. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
29. 29. Using Linked Lists Random doesn’t really mean “random,” it means “arbitrary”– go directly to any specific item without having to go through all of the items before it in the sequence to get there, C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
31. 31. Using Linked Lists Just like vector, the standard list is a template. You define it by specifying the type it will hold, list<string> names; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
32. 32. Using Linked Lists Just like vector, the standard list is a template. You define it by specifying the type it will hold, and use the push_back method to put items into it: list<string> names; names.push_back("Tom"); names.push_back("Dick"); names.push_back("Harry"); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
33. 33. Using Linked Lists Recall that you cannot go directly to an element in the list using [ ]. …names[2]… C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
35. 35. Using Linked Lists To have pos mark the beginning position in the names list, you use the begin method of the list : list<string>::iterator pos; pos = names.begin(); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
36. 36. Using Linked Lists To move pos to the next position in the names list, you use ++ list<string>::iterator pos; pos = names.begin(); pos++; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
37. 37. Using Linked Lists To move pos backward, you use -- list<string>::iterator pos; pos = names.begin(); pos++; pos--; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
38. 38. Using Linked Lists To obtain the value that pos indicates, you use * list<string>::iterator pos; pos = names.begin(); pos++; pos--; string value = *pos; // store the value from // the list into value *pos = "Romeo"; // The list value at the // position is changed C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
40. 40. Using Linked Lists Beware the dangers of getting these expressions confused: * pos pos the value in the the iterator that list at pos indicates a position in the list C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
42. 42. Using Linked Lists Beware the dangers of getting these expressions confused: *pos = "Romeo"; // The list value at the // position is changed C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
43. 43. Using Linked Lists Beware the dangers of getting these expressions confused: *pos = "Romeo"; // The list value at the // position is changed pos = names.begin(); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
44. 44. Using Linked Lists Beware the dangers of getting these expressions confused: *pos = "Romeo"; // The list value at the // position is changed pos = names.begin(); // The position is again at // the beginning of the list C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
45. 45. Using Linked Lists Beware the dangers of getting these expressions confused: *pos = "Romeo"; // The list value at the // position is changed pos = names.begin(); // The position is again at // the beginning of the list C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
46. 46. Using Linked Lists The insert method here to insert a new element and the value for that new element: names.insert(pos, "Romeo"); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
47. 47. Using Linked Lists This convention makes it easy to insert a new element before the first value of a list: pos = names.begin(); names.insert(pos, "Romeo"); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
48. 48. Using Linked Lists There is also an end method for lists which indicates the position AFTER the last one. That is exactly where a new last element should go: pos = names.end(); // Points past the end of the list names.insert(pos, "Juliet"); // Insert past the end of the list, // A new last element is appended C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
49. 49. Using Linked Lists Because end indicates the position AFTER the last one, using that position is an error, just as it is an error to access an element in an array past the last element. string value = *names.end(); ERROR!!! C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
50. 50. Using Linked Lists The begin and end methods are used when looping through all the elements in a list. pos = names.begin(); while (pos != names.end()) { cout << *pos << endl; pos++; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
51. 51. Using Linked Lists The begin and end methods are used when looping through all the elements in a list. pos = names.begin(); while (pos != names.end()) { cout << *pos << endl; pos++; } Or more correctly with a for loop: for (pos = names.begin(); pos != names.end(); pos++) { cout << *pos << endl; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
52. 52. Using Linked Lists But notice something VERY important: pos = names.begin(); while (pos != names.end()) { cout << *pos << endl; pos++; } for (pos = names.begin(); pos != names.end(); pos++) { cout << *pos << endl; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
53. 53. Using Linked Lists But notice something VERY important: in the test, we are NOT using < or <=, we are using != pos = names.begin(); while (pos != names.end()) { cout << *pos << endl; pos++; } for (pos = names.begin(); pos != names.end(); pos++) { cout << *pos << endl; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
54. 54. Using Linked Lists But notice something VERY important: in the test, we are NOT using < or <=, we are using != pos = names.begin(); while (pos != names.end()) { cout << *pos << endl; pos++; } for (pos = names.begin(); pos != names.end(); pos++) { cout << *pos << endl; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
55. 55. Using Linked Lists The elements in a linked list are not arranged as in an array, so the less-than relationship cannot be assumed. pos = names.begin(); while (pos != names.end()) { cout << *pos << endl; pos++; } for (pos = names.begin(); pos != names.end(); pos++) { cout << *pos << endl; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
56. 56. Using Linked Lists The erase method removes an element at a position: pos = names.begin(); pos++; pos = names.erase(pos); This code removes the second element from the list. erase returns the position after the one removed so pos now points to what was the third element. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
58. 58. Using Linked Lists#include <string> ch13/list1.cpp#include <list>#include <iostream>using namespace std;int main(){ list<string> names; names.push_back("Tom"); names.push_back("Dick"); names.push_back("Harry"); names.push_back("Juliet"); // Add a value in fourth place list<string>::iterator pos = names.begin(); pos++; pos++; pos++; names.insert(pos, "Romeo"); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
59. 59. Using Linked Lists ch13/list1.cpp // Remove the value in second place pos = names.begin(); pos++; names.erase(pos); // Print all values for (pos = names.begin(); pos != names.end(); pos++) { cout << *pos << endl; } return 0;} C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
60. 60. Implementing Linked Lists Recall that we said that the values in a list are really stored in separate memory blocks. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
61. 61. Implementing Linked Lists The list class of the STL defines many useful member functions. For simplicity, we will only study the implementation of the most useful ones: push_back, insert, erase, and the iterator operations. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
62. 62. Implementing Linked Lists A doubly linked list stores each value in a Node. So we will start with its definition: class Node { public: Node(string s); private: string data; Node* previous; Node* next; friend class List; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
63. 63. Implementing Linked Lists A Node object holds a value, and pointers to the previous and next Nodes: class Node { public: Node(string s); private: string data; Node* previous; Node* next; friend class List; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
64. 64. Implementing Linked Lists When a Node is created, its previous and next pointers are set to NULL in the constructor. class Node { public: Node(string s); private: string data; Node* previous; Node* next; friend class List; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
65. 65. Implementing Linked Lists friendship declarations allows the List and Iterator member functions to inspect and directly modify the private: data members of the Node class. class Node { public: Node(string s); private: string data; Node* previous; Node* next; friend class List; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
66. 66. Implementing Linked Lists friendship declarations allows the List and Iterator member functions to inspect and directly modify the private: data members of the Node class. class Node { public: Node(string s); private: string data; Node* previous; Node* next; friend class List; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
67. 67. Implementing Linked Lists A class should not grant friendship to another class lightly, because it breaks the privacy protection. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
68. 68. Implementing Linked Lists We will call our class List, with an uppercase L, to differentiate it from the standard list class template. class List { public: List(); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
69. 69. Implementing Linked Lists A List object holds the locations of the first and last Nodes in the list: class List { public: List(); void push_back(string data); void insert(Iterator pos, string s); Iterator erase(Iterator pos); Iterator begin(); Iterator end(); private: Node* first; Node* last; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
70. 70. Implementing Linked Lists It does not store any data – only pointers that point to the first as last Nodes in the list. The List’s data is in the Nodes! class List { public: List(); void push_back(string data); void insert(Iterator pos, string s); Iterator erase(Iterator pos); Iterator begin(); Iterator end(); private: Node* first; Node* last; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
71. 71. Implementing Linked Lists If first and last are NULL, the list is empty. class List { public: List(); void push_back(string data); void insert(Iterator pos, string s); Iterator erase(Iterator pos); Iterator begin(); Iterator end(); private: Node* first; Node* last; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
72. 72. Implementing Linked Lists Our List object will have, as the STL list does, the methods push_back, insert and erase as well as the begin() and end() methods that work with (our) Iterator class. class List { public: List(); void push_back(string data); void insert(Iterator pos, string s); Iterator erase(Iterator pos); Iterator begin(); Iterator end(); private: Node* first; Node* last; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
73. 73. Implementing Linked Lists And we befriend the Iterator class. class List { public: List(); void push_back(string data); void insert(Iterator pos, string s); Iterator erase(Iterator pos); Iterator begin(); Iterator end(); private: Node* first; Node* last; friend class Iterator; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
74. 74. Implementing Linked Lists And now for the Iterator class. It indicates a position in a List. class Iterator { public: Iterator(); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
75. 75. Implementing Linked Lists It has a pointer to the “current” Node’s position and a pointer to the List that created it (the List that the Node is in). class Iterator { public: Iterator(); private: Node* position; List* container; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
76. 76. Implementing Linked Lists An STL iterator supports the operators: * (get the value at) ++ (next) -- (previous) == (equals) so we will write methods using those names. class Iterator { public: Iterator(); string get() const; void next(); void previous(); bool equals(Iterator b) const; private: Node* position; List* container; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
77. 77. Implementing Linked Lists And we grant friend status to our List class. class Iterator { public: Iterator(); string get() const; void next(); void previous(); bool equals(Iterator b) const; private: Node* position; List* container; friend class List; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
78. 78. Implementing Linked Lists If an Iterator points past the end of a List, then the position pointer is NULL. class Iterator { public: Iterator(); string get() const; void next(); void previous(); bool equals(Iterator b) const; private: Node* position; List* container; friend class List; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
79. 79. Implementing Linked Lists In this situation, if the previous member function is called, the container pointer is used to set the position pointer to the last element of the List. class Iterator { public: Iterator(); string get() const; void next(); void previous(); bool equals(Iterator b) const; private: Node* position; List* container; friend class List; }; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
84. 84. Implementing Linked Lists An Iterator on the List is shown pointing at the first Node in “the list”. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
85. 85. Implementing Linked Lists Iterators are created by the begin and end member functions of the List class. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
86. 86. Implementing Linked Lists The begin method creates an Iterator whose position pointer points to the first node in the List. The Iterator’s container is set to the correct List, the one that begin should be pointing into – this one. Iterator List::begin() { Iterator iter; iter.position = first; iter.container = this; return iter; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
87. 87. Implementing Linked Lists The end method creates an Iterator whose position pointer is NULL. We choose NULL to mean the past-the-end position The Iterator’s container is also set to the correct List. Iterator List::end() { Iterator iter; iter.position = NULL; iter.container = this; return iter; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
89. 89. Implementing Linked Lists Because the Iterator’s position field points to the Node whose next pointer C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
90. 90. Implementing Linked Lists Because the Iterator’s position field points to the Node whose next pointer points to the Node that the Iterator’s position field should point to after the next method is finished… C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
94. 94. Implementing Linked Lists It is an error to dereference a NULL pointer so you can evaluate position->next only if position is not NULL. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
95. 95. Implementing Linked Lists That makes it illegal to advance an Iterator once it is in the past-the-end position (NULL). Should our implementation check for this error? The implementation of the standard C++ library doesn’t. (!) So we won’t either. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
96. 96. Implementing Linked Lists The previous method is a bit more complex. In most cases it’s: position = position->previous; which is just the “opposite” of what the next method does. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
97. 97. Implementing Linked Lists However, if an Iterator is currently past-the-end, then you must make it point to the last element in the List it is on. void Iterator::previous() { if (position == NULL) { position = container->last; } else { position = position->previous; } } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
98. 98. Implementing Linked Lists The get method simply returns the data value of the Node to which position points. string Iterator::get() const { return position->data; } It is illegal to call get if an Iterator points past-the-end of the List. And again we follow the STL’s lead and don’t check for this. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
99. 99. Implementing Linked Lists To test if two Iterators (this one and another one) are pointing to the same Node (in the same List) the equals method compares their two position pointers. bool Iterator::equals(Iterator b) const { return position == b.position; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
100. 100. Implementing Linked Lists When the List is not empty, the push_back method appends a new Node to the end of the List. NULL C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
101. 101. Implementing Linked Lists When the List is not empty, the push_back method appends a new Node to the end of the List. NULL C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
102. 102. Implementing Linked Lists When the List is not empty, the push_back method appends a new Node to the end of the List. NULL C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
103. 103. Implementing Linked Lists When the List is not empty, the push_back method appends a new Node to the end of the List. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
109. 109. Implementing Linked Lists Node* new_node = new Node(s); new_node->previous = last; last->next = new_node; NULL C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
111. 111. Implementing Linked Lists Node* new_node = new Node(s); new_node->previous = last; last->next = new_node; last = new_node; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
112. 112. Implementing Linked Lists Node* new_node = new Node(s); new_node->previous = last; last->next = new_node; last = new_node; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
113. 113. Implementing Linked Lists When last is NULL, which can happen only when the List is empty, after the call to push_back, the Node has a single Node—namely, new_node. void List::push_back(string data) { Node* new_node = new Node(data); if (last == NULL) // List is empty { first = new_node; last = new_node; } else { new_node->previous = last; last->next = new_node; last = new_node; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved }
116. 116. Implementing Linked Lists Inserting into the middle of a List is a bit more difficult. void List::insert(Iterator iter, string s); This will insert a new Node containing s at iter.position. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
121. 121. Implementing Linked Lists What happens if you are inserting past-the-end of the list? iter.position would be NULL. void List::insert(Iterator iter, string s) { C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
122. 122. Implementing Linked Lists What happens if you are inserting past-the-end of the list? iter.position would be NULL. Call push_back and you are done. void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
123. 123. Implementing Linked Lists Give names to the surrounding nodes. Let before be the Node before the insertion location, and let after be the Node after that: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
124. 124. Implementing Linked Lists Give names to the surrounding nodes. Let before be the Node before the insertion location, and let after be the Node after that: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
125. 125. Implementing Linked Lists Create the new Node: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
126. 126. Implementing Linked Lists Create the new Node: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
127. 127. Implementing Linked Lists Connect the new Node: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
128. 128. Implementing Linked Lists Connect the new Node: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); new_node->previous = before; new_node->next = after; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
129. 129. Implementing Linked Lists Connect the after Node: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); new_node->previous = before; new_node->next = after; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
130. 130. Implementing Linked Lists Connect the after Node to the new node: void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); new_node->previous = before; new_node->next = after; after->previous = new_node; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
131. 131. Implementing Linked Lists Connecting the before Node depends. void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); new_node->previous = before; new_node->next = after; after->previous = new_node; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
132. 132. Implementing Linked Lists Are we at the start of the List or not? void List::insert(Iterator iter, string s) { if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); new_node->previous = before; new_node->next = after; after->previous = new_node; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
133. 133. Implementing Linked Lists At the start, before would be NULL and the new Node would be added at the start, otherwise, we just adjust the pointer. ... if (before == NULL) // Insert at beginning { first = new_node; } else { before->next = new_node; } } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
134. 134. Implementing Linked Lists Finally, look at the implementation of the erase method: Iterator List::erase(Iterator iter); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
135. 135. Implementing Linked Lists This will delete the Node at iter.position, reset the pointers in the Node s before and after it, and return an Iterator that points to the Node after the one that was removed. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
136. 136. Implementing Linked Lists This will delete the Node at iter.position, reset the pointers in the Node s before and after it, and return an Iterator that points to the Node after the one that was removed. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
138. 138. Implementing Linked Lists Create variables for the Node to be removed, the Node before it, and the Node after it: Iterator List::erase(Iterator iter) { C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
139. 139. Implementing Linked Lists Create variables for the Node to be removed, the Node before it, and the Node after it: Iterator List::erase(Iterator iter) { Node* remove = iter.position; Node* before = remove->previous; Node* after = remove->next; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
140. 140. Implementing Linked Lists Update the next and previous pointers of the before and after Nodes to bypass the node that is to be removed: Iterator List::erase(Iterator iter) { Node* remove = iter.position; Node* before = remove->previous; Node* after = remove->next; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
141. 141. Implementing Linked Lists Update the next and previous pointers of the before and after Nodes to bypass the node that is to be removed: Iterator List::erase(Iterator iter) { Node* remove = iter.position; Node* before = remove->previous; Node* after = remove->next; before->next = after; after->previous = before; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
142. 142. Implementing Linked Lists But wait! What if we are at either end of the List? Iterator List::erase(Iterator iter) { Node* remove = iter.position; Node* before = remove->previous; Node* after = remove->next; before->next = after; after->previous = before; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
143. 143. Implementing Linked Lists Then either of before and after would NULL? So instead of just assigning, we need to check: ... Node* after = remove->next; if (remove == first) { first = after; } else { before->next = after; } if (remove == last) { last = before; } else { after->previous = before; C++ for Everyone by Cay Horstmann } Copyright © 2012 by John Wiley & Sons. All rights reserved
144. 144. Implementing Linked Lists You must adjust the Iterator’s position so it no longer points to the removed element. ... after->previous = before; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
145. 145. Implementing Linked Lists You must adjust the Iterator‘s position so it no longer points to the removed element. ... after->previous = before; } iter.position = after; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
146. 146. Implementing Linked Lists Finally, recycle the removed node: ... after->previous = before; } iter.position = after; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
147. 147. Implementing Linked Lists Finally, recycle the removed node: ... after->previous = before; } iter.position = after; delete remove; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
148. 148. Implementing Linked Lists But wait! Again there’s more. ... after->previous = before; } iter.position = after; delete remove; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
149. 149. Implementing Linked Lists But wait! Again there’s more. ... after->previous = before; } iter.position = after; delete remove; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
150. 150. Implementing Linked Lists You must return the Iterator that points to the Node after the one that was removed: ... after->previous = before; } iter.position = after; delete remove; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
151. 151. Implementing Linked Lists You must return the Iterator that points to the Node after the one that was removed: ... after->previous = before; } iter.position = after; delete remove; Iterator r; r.position = after; r.container = this; return r; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
153. 153. Implementing Linked Lists ch13/list2.cpp#include <string>#include <iostream>using namespace std;class List;class Iterator;class Node{public: /** Constructs a node with a given data value. @pram s the data to store in this node */ Node(string s);private: string data; Node* previous; Node* next;friend class List;friend class Iterator;}; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
154. 154. Implementing Linked Lists ch13/list2.cppclass List{public: /** Constructs an empty list. */ List(); /** Appends an element to the list. @pram data the value to append */ void push_back(string data); /** Inserts an element into the list. @pram iter the position before which to insert @pram s the value to append */ void insert(Iterator iter, string s); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
155. 155. Implementing Linked Lists ch13/list2.cpp /** Removes an element from the list. pram iter the position to remove @return an iterator pointing to the element after the erased element */ Iterator erase(Iterator iter); /** Gets the beginning position of the list. @return an iterator pointing to the beginning of the list */ Iterator begin(); /** Gets the past-the-end position of the list. @return an iterator pointing past the end of the list */ Iterator end(); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
156. 156. Implementing Linked Lists ch13/list2.cppprivate: Node* first; Node* last;friend class Iterator;};class Iterator{public: /** Constructs an iterator that does not point into any list. */ Iterator(); /** Looks up the value at a position. @return the value of the node to which the iterator points */ string get() const; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
157. 157. Implementing Linked Lists ch13/list2.cpp /** Advances the iterator to the next node. */ void next(); /** Moves the iterator to the previous node. */ void previous(); /** Compares two iterators. @pram b the iterator to compare with this iterator @return true if this iterator and b are equal */ bool equals(Iterator b) const;private: Node* position; List* container;friend class List;}; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
158. 158. Implementing Linked Lists ch13/list2.cppNode::Node(string s){ data = s; previous = NULL; next = NULL;}List::List(){ first = NULL; last = NULL;}void List::push_back(string data){ Node* new_node = new Node(data); if (last == NULL) // List is empty { first = new_node; last = new_node; } C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
159. 159. Implementing Linked Lists ch13/list2.cpp else { new_node->previous = last; last->next = new_node; last = new_node; }}void List::insert(Iterator iter, string s){ if (iter.position == NULL) { push_back(s); return; } Node* after = iter.position; Node* before = after->previous; Node* new_node = new Node(s); new_node->previous = before; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
160. 160. Implementing Linked Lists ch13/list2.cpp else { before->next = after; } if (remove == last) { last = before; } else { after->previous = before; } delete remove; Iterator r; reposition = after; r.container = this; return r;} C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
161. 161. Implementing Linked Lists ch13/list2.cppIterator List::begin(){ Iterator iter; iter.position = first; iter.container = this; return iter;}Iterator List::end(){ Iterator iter; iter.position = NULL; iter.container = this; return iter;}Iterator::Iterator(){ position = NULL; container = NULL;} C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
162. 162. Implementing Linked Lists ch13/list2.cppstring Iterator::get() const{ return position->data;}void Iterator::next(){ position = position->next;}void Iterator::previous(){ if (position == NULL) { position = container->last; } else { position = position->previous; }} C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
163. 163. Implementing Linked Lists ch13/list2.cppbool Iterator::equals(Iterator b) const{ return position == b.position;}int main(){ List names; names.push_back("Tom"); names.push_back("Dick"); names.push_back("Harry"); names.push_back("Juliet"); // Add a value in fourth place Iterator pos = names.begin(); pos.next(); pos.next(); pos.next(); names.insert(pos, "Romeo"); C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
164. 164. Implementing Linked Lists ch13/list2.cpp // Remove the value in second place pos = names.begin(); pos.next(); names.erase(pos); // Print all values for (pos = names.begin(); !pos.equals(names.end()); pos.next()) { cout << pos.get() << endl; } return 0;} C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
165. 165. The Efficiency of List, Array, and Vector Operations How efficient are these operations: • Getting the kth element • Adding or removing an element at a given position (an iterator or index) • Adding or removing an element at the end for lists, arrays, and vectors? C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
166. 166. The Efficiency of List, Array, and Vector Operations list – getting the kth element Getting to the kth element requires starting at the beginning and advancing the iterator k times. If it takes time T to advance the iterator once, advancing the iterator to the kth element takes kT time so locating the kth element is an O(k) operation. Advancing an iterator does some checking — this quantity of time is independent of the iterator position. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
167. 167. The Efficiency of List, Array, and Vector Operations array – getting the kth element Getting to the kth element requires only a calculation for [ ] to go directly to the kth element. A simple calculation is O(1), so locating the kth element is an O(1) operation. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
168. 168. The Efficiency of List, Array, and Vector Operations vector – getting the kth element Getting to the kth element, just as with an array, requires only a calculation for [ ] to go directly to the kth element. The calculation is slightly more involved but it is still a simple calculation, so locating the kth element is an O(1) operation. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
169. 169. The Efficiency of List, Array, and Vector Operations list – inserting and deleting These operations involve only changing two pointer values. Clearly O(1) operations. Note that we will have already done the searching for where to do the insert or delete so that time is not considered here. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
170. 170. The Efficiency of List, Array, and Vector Operations array – inserting and deleting vector – inserting and deleting Arrays are easy to visualize. Inserting and deleting for vector requires seeing how the vector class is implemented. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
171. 171. The Efficiency of List, Array, and Vector Operations vector – internal organization A vector keeps its data in a dynamic buffer (an array) C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
172. 172. The Efficiency of List, Array, and Vector Operations vector – internal organization A vector keeps its data in a dynamic buffer (an array) and a pointer to that area; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
173. 173. The Efficiency of List, Array, and Vector Operations vector – internal organization A vector keeps its data in a dynamic buffer (an array) and a pointer to that area; it keeps the value of the current capacity of the buffer; C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
174. 174. The Efficiency of List, Array, and Vector Operations vector – internal organization A vector keeps its data in a dynamic buffer (an array) and a pointer to that area; it keeps the value of the current capacity of the buffer; and it keeps the number of elements currently in the buffer. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
175. 175. The Efficiency of List, Array, and Vector Operations array – inserting and deleting vector – inserting and deleting Because the vector’s data is stored in an array, the analysis for both of these is similar: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
176. 176. The Efficiency of List, Array, and Vector Operations array – inserting and deleting vector – inserting and deleting In both, to insert an element at position k, the elements with higher index values must be moved C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
177. 177. The Efficiency of List, Array, and Vector Operations array – inserting and deleting vector – inserting and deleting In both, to insert an element at position k, the elements with higher index values must be moved to make room for the new element. And size would be increased by one. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
178. 178. The Efficiency of List, Array, and Vector Operations array – inserting and deleting vector – inserting and deleting To delete an element at position k, the elements with higher index values must be moved to take up the room that had been used for the deleted element value. And size would be reduced by one. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
179. 179. The Efficiency of List, Array, and Vector Operations array – inserting and deleting vector – inserting and deleting For the analysis, we need to know many elements are affected in a move. For simplicity, we will assume that insertions and deletions happen at random locations. Then, on average, where n is the size of the array or vector, each insertion or deletion moves n ̸ 2 elements Insert and delete are O(n) operations. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
180. 180. The Efficiency of List, Array, and Vector Operations list – adding or removing an element at the end If we assume the list has a “maintenance pointer” which points to the last item in the list, then, same as always, just reset some pointer values: an O(1) operation. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
181. 181. The Efficiency of List, Array, and Vector Operations array – adding or removing an element at the end vector – adding or removing an element at the end The array and vector will have to be considered separately. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
182. 182. The Efficiency of List, Array, and Vector Operations array – adding or removing an element at the end The array must be large enough to insert at the end or we simply cannot insert. Inserting and deleting involve [ ], a simple calculation as before, plus arithmetic on the size. There is no moving of data. O(1). C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
183. 183. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end To insert at the end of a vector, the push_back method is used. When the capacity is sufficient, this is an O(1) process requiring only accessing and assigning to a position already there in the dynamic array (the buffer) and arithmetic on the size. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
184. 184. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end When the buffer is filled to its current capacity, v.push_back(9); 5 5 C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
185. 185. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end When the buffer is filled to its current capacity, the buffer will be increased in size to accommodate the call to the push_back method v.push_back(9); 5 5 C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
186. 186. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end When the buffer is filled to its current capacity, the buffer will be increased in size to accommodate the call to the push_back method v.push_back(9); 5 10 C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
187. 187. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end When the buffer is filled to its current capacity, the buffer will be increased in size to accommodate the call to the push_back method v.push_back(9); 6 10 C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
188. 188. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end The reallocation does not happen very often. That helps with the efficiency. But makes the analysis a bit harder. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
189. 189. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end The reallocation algorithm effects the analysis also. Suppose we choose to double the size with each reallocation. If we start a vector with capacity 10, we must reallocate when the buffer reaches sizes 10, 20, 40, 80, 160, 320, 640, 1280, and so on. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
190. 190. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Assume that one insertion without reallocation takes time T1 . Assume that reallocation of k elements takes time kT2. What is the cost of 1,280 push_back operations? C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
191. 191. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Of course, we pay 1280 * T1 for the 1280 insertions. The reallocation cost is: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
192. 192. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Of course, we pay 1280 * T1 for the 1280 insertions. The reallocation cost is: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
193. 193. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Of course, we pay 1280 * T1 for the 1280 insertions. The reallocation cost is: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
194. 194. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Of course, we pay 1280 * T1 for the 1280 insertions. The reallocation cost is: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
195. 195. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Of course, we pay 1280 * T1 for the 1280 insertions. The reallocation cost is: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
196. 196. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Of course, we pay 1280 * T1 for the 1280 insertions. The reallocation cost is: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
197. 197. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end The total cost is a bit less than for 1280 insertions: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
198. 198. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end The cost of n push_back operations is then less than: C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
199. 199. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end Because the second factor is a constant, we conclude that n push_back operations take O(n) time. But Wait! C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
200. 200. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end We know that it isn’t quite true that an individual push_back operation takes O(1) time because occasionally a push_back is unlucky and must reallocate the buffer. C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
201. 201. The Efficiency of List, Array, and Vector Operations vector – adding or removing an element at the end But if the cost of that reallocation is distributed over the preceding push_back operations, then the surcharge for each of them is still a constant amount. We say that push_back takes amortized O(1) time, which is written as O(1)+. Much better than O(n). (Thank you accountants of the world!) C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved
202. 202. The Efficiency of List, Array, and Vector Operations So now, how efficient are these operations for lists, arrays, and vectors? C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved