Download presentation
Presentation is loading. Please wait.
Published byRegina Morton Modified over 9 years ago
1
1 C++ Classes and Data Structures Jeffrey S. Childs Chapter 8 Stacks and Queues Jeffrey S. Childs Clarion University of PA © 2008, Prentice Hall
2
2 Stack ADT Recall that ADT is abstract data type, a set of data and a set of operations that act upon the data In a stack, the set of data is the stack of elements
3
3 Stack ADT Operations push: places an element onto the top of a stack pop: removes an element from the top of the stack peek: which retrieves (copies) a value from the top of the stack without removing it an operation to determine whether or not the stack is empty an operation to empty out a stack
4
4 Push 17 5 11 3 Push means place a new data element at the top of the stack
5
5 Push (cont.) 17 5 11 3 Push means place a new data element at the top of the stack
6
6 Push (cont.) 17 5 11 3 Push means place a new data element at the top of the stack
7
7 Push (cont.) 17 5 11 3 Push means place a new data element at the top of the stack
8
8 Pop 17 5 11 3 Pop means take a data element off the top of the stack
9
9 Pop (cont.) 17 5 11 3 Pop means take a data element off the top of the stack
10
10 Pop (cont.) 17 5 11 3 Pop means take a data element off the top of the stack
11
11 Pop (cont.) 17 5 11 3 Pop means take a data element off the top of the stack
12
12 Peek 17 5 11 3 Peek means retrieve the top of the stack without removing it
13
13 Peek (cont.) 17 5 11 3 3 Peek means retrieve the top of the stack without removing it
14
14 Peek (cont.) 17 5 11 3 3 Peek means retrieve the top of the stack without removing it
15
15 1 #include “Array.h” 2 3 template 4 class Stack 5 { 6 public: 7Stack( ); 8void push( DataType elementToPush ); 9bool pop( DataType & poppedElement ); 10bool peek( DataType & topElement ); 11bool isEmpty( ) const; 12void makeEmpty( ); 13 private: 14Array elements; 15int top; 16 }; 17 18 #include “Stack.cpp” Stack Class Template
16
16 1 #include “Array.h” 2 3 template 4 class Stack 5 { 6 public: 7Stack( ); 8void push( DataType elementToPush ); 9bool pop( DataType & poppedElement ); 10bool peek( DataType & topElement ); 11bool isEmpty( ) const; 12void makeEmpty( ); 13 private: 14Array elements; 15int top; 16 }; 17 18 #include “Stack.cpp” Stack Class Template (cont.)
17
17 1 #include “Array.h” 2 3 template 4 class Stack 5 { 6 public: 7Stack( ); 8void push( DataType elementToPush ); 9bool pop( DataType & poppedElement ); 10bool peek( DataType & topElement ); 11bool isEmpty( ) const; 12void makeEmpty( ); 13 private: 14Array elements; 15int top; 16 }; 17 18 #include “Stack.cpp” Stack Class Template (cont.) used as an index to the top of the stack
18
18 The Actual Pop 125 25 200 70 elements 0 1 2 3 top An element can’t really be removed from an array, as one would think pop would achieve.
19
19 The Actual Pop (cont.) 125 25 200 70 elements 0 1 2 3 top The element 70 is at the top of the stack, and what really happens during a pop, is that 70 is returned to the client…
20
20 The Actual Pop (cont.) 125 25 200 70 elements 0 1 2 3 top The element 70 is at the top of the stack, and what really happens during a pop, is that 70 is returned to the client… client
21
21 The Actual Pop (cont.) 125 25 200 70 elements 0 1 2 3 top and top is decremented… client
22
22 The Actual Pop (cont.) 125 25 200 70 elements 0 1 2 3 top and top is decremented… client
23
23 The Actual Pop (cont.) 125 25 200 70 elements 0 1 2 3 top The element 70 is still in the array, but it is no longer accessible. The next push will overwrite it. Say, we would like to push 63… client
24
24 The Actual Push (cont.) 125 25 200 70 elements 0 1 2 3 top First, top is incremented…
25
25 The Actual Push (cont.) 125 25 200 70 elements 0 1 2 3 top First, top is incremented…
26
26 The Actual Push (cont.) 125 25 200 70 elements 0 1 2 3 top Then, 63 is pushed into that position…
27
27 The Actual Push (cont.) 125 25 200 63 elements 0 1 2 3 top Then, 63 is pushed into that position…
28
28 1 template 2 Stack ::Stack( ) 3: elements( 2 ), top( -1 ) 4 { 5 } Stack Constructor
29
29 Shift Operators Shift operators are used in the array implementations of data structures They are appropriate when multiplying or dividing by powers of two They are faster than multiplication and division Assume num is a positive integer. num << n is the same as num * 2 n num >> n is the same as num / 2 n (using integer division)
30
30 Push Code 6 template 7 void Stack ::push( 8DataType elementToPush ) 9 { 10if ( ++top == elements.length( ) ) 11 elements.changeSize( elements.length( ) << 1 ); 12elements[ top ] = elementToPush; 13 }
31
31 Pop Recall…to conserve memory, if the number of used elements of an array drops to 25% of the capacity, we want to cut the capacity of the array in half On each pop, it is possible that we may want to reduce the size of the array
32
32 Reducing Array Size When we call the changeSize function for the Array object, it is possible that there is not enough heap memory to reduce the array size A new, smaller dynamic array needs to be created to copy the elements of the old, larger dynamic array to it If the smaller array cannot be created the pop function should still succeed (stack is still completely functional)
33
33 Reducing Array Size (cont.) If array size reduction does not succeed, it might succeed later on –Other dynamic memory may be freed –The number of used elements in the stack may drop so low that a small dynamic array can be made Therefore, in the pop function, we should try to reduce the size to the smallest power of 2, which is: –At least twice the number of elements being used –At least 2
34
34 Example Suppose there are 3 elements being used in a stack. top would be 2, so top + 1 gives the number of elements Suppose also that the capacity of the array is 32. The array’s capacity should be reduced to 8 (one quarter of the capacity instead of one half)
35
35 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:
36
36 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:
37
37 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32
38
38 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32
39
39 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32 Number of elements: 3
40
40 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32 Number of elements: 3
41
41 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32 Number of elements: 3 trysize / 4 : 8
42
42 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32 Number of elements: 3 trysize / 4 : 8 TRUE
43
43 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32 Number of elements: 3 trysize / 4 : 8 TRUE
44
44 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32 Number of elements: 3 trysize / 4 : 8 TRUE
45
45 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:32
46
46 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:16
47
47 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:16
48
48 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:16 3 <= 4 : TRUE
49
49 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:16 3 <= 4 : TRUE
50
50 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:16 3 <= 4 : TRUE TRUE
51
51 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:16
52
52 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:8
53
53 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:8
54
54 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:8 3 <= 2 : FALSE
55
55 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:8
56
56 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:8 trysize will be the new capacity that we attempt to use (might be out of heap memory)
57
57 Example (cont.) int trysize = elements.length( ); while ( ( top + 1 > 2 ) && trysize > 2 ) trysize >>= 1; top:2 capacity:32 trysize:8 If trysize would become 2, this part would be false, causing 2 to be the smallest possible capacity
58
58 14 template 15 bool Stack ::pop( 16DataType & poppedElement ) 17 { 18if ( top == -1 ) 19return false; 20poppedElement = elements[ top ]; 21top--; 22int trysize = elements.length( ); 23while ( ( top + 1 > 2 ) && trysize > 2 ) 24trysize >>= 1; Pop Code Pop code continued…
59
59 Pop Code (cont.) 25if ( trysize < elements.length( ) ) { 26try { 27elements.changeSize( trysize ); 28} 29catch( … ) { } 30} 31 32return true; 33 }
60
60 Peek 34 // returns the element at the top of the stack in 35 // topElement without removing it. Returns false if 36 // called on an empty stack; otherwise, returns true 37 template 38 bool Stack ::peek( 39 DataType & topElement ) 40 { 41if ( top == -1 ) 42return false; 43topElement = elements[ top ]; 44return true; 45 }
61
61 46 template 47 bool Stack ::isEmpty( ) const 48 { 49return top == -1; 50 } isEmpty
62
62 makeEmpty 51 template 52 void Stack ::makeEmpty( ) 53 { 54top = -1; 55try { 56elements.changeSize( 2 ); 57} 58catch( … ) { } 59 }
63
63 Linked-List Stack Stacks can also be implemented with a linked list The front node is the top of the stack
64
64 Linked-List Stack (cont.) top To pop, we remove the node at the front of the linked list, and return the element to the client…
65
65 Linked-List Stack (cont.) top To pop, we remove the node at the front of the linked list, and return the element to the client…
66
66 Linked-List Stack (cont.) top To push, we place the new element in a node and insert it at the front of the linked list…
67
67 Linked-List Stack (cont.) To push, we place a new element in a node and insert it at the front of the linked list… top
68
68 The Queue ADT The queue is a data structure that is like a line of people, except that it is a line of elements The line of elements is the data upon which operations are performed
69
69 Queue ADT Operations enqueue: add an element to the end of the line dequeue: take an element from the front of the line peek: retrieve (copy) the element at the front of the line without removing it an operation to determine whether or not the queue is empty an operation that will empty out the queue
70
70 Queue A queue is like a line of people When people join the line, they go at the end When people are served, they come off the front of the line A queue is a FIFO (first-in, first-out) data structure It is used in situations where a fair first- come, first-serve basis is called for, like a print queue
71
71 Queue (cont.) In addition to a pointer at the beginning of the linked list (called front), a pointer to the end of the linked list (called back) is also maintained in the private section The back pointer makes it fast to add new elements to the end of the queue – you don’t have to use a loop to go all the way through the queue to find the last node
72
72 Header Node A header node can simplify the code for a linked-list queue We make use of a header node in the queue implementation
73
73 Dequeue Operation front back header
74
74 Dequeue Operation (cont.) front back header
75
75 Enqueue Operation front back header
76
76 Enqueue Operation (cont.) front back header
77
77 1 // queue.h -- class template for the linked list 2 // implementation of a queue 3 // note: use of the copy constructor, overloaded 4 // assignment operator, or enqueue function can cause an 5 // exception to be thrown when heap memory is exhausted 6 7 template 8 struct Node { 9DataType info; 10Node *next; 11 }; Queue Specification File Specification File continued…
78
78 Queue Specification File (cont.) 12 template 13 class Queue 14 { 15 public: 16Queue( ); 17Queue( const Queue & apqueue ); 18~Queue( ); 19Queue & operator =( 20 const Queue & rqueue ); public section of Queue continued…
79
79 Queue Specification File (cont.) 21void enqueue( const DataType & element ); 22bool dequeue( DataType & deqElement ); 23bool peek( DataType & frontElement ); 24bool isEmpty( ) const; 25void makeEmpty( ); private section of Queue is next…
80
80 Queue Specification File (cont.) 26 private: 27Node *front; 28Node *back; 29Node header; 30inline void deepCopy( 31const Queue & original ); 32 }; 33 34 #include "queue.cpp"
81
81 1 // queue.cpp 2 3 template 4 Queue ::Queue( ) 5 { 6front = back = &header; 7 } Queue Constructor
82
82 Queue Copy Constructor and Destructor 8 template 9 Queue ::Queue( 10const Queue & apqueue ) 11 { 12deepCopy( apqueue ); 13 } 14 15 template 16 Queue ::~Queue( ) 17 { 18makeEmpty( ); 19 }
83
83 Queue Overloaded Assignment Operator 20 template 21 Queue & Queue :: 22 operator =( const Queue & rqueue ) 23 { 24if ( this == &rqueue ) 25return *this; 26makeEmpty( ); 27deepCopy( rqueue ); 28return *this; 29 }
84
84 Enqueue 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } This section creates the new node to enqueue and places element within in it…
85
85 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } This section creates the new node to enqueue and places element within in it… ptr
86
86 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Let’s consider a couple of cases with these next two lines. ptr
87
87 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Let’s consider a couple of cases with these next two lines. ptr
88
88 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 1: The queue is initially empty. ptr
89
89 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 1: The queue is initially empty. front ptr header back
90
90 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 1: The queue is initially empty. front ptr header back
91
91 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 1: The queue is initially empty. front ptr header back
92
92 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 1: The queue is initially empty. front ptr header back
93
93 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 1: The queue is initially empty. front ptr header back
94
94 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 2: The queue has nodes. ptr
95
95 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 2: The queue has nodes. ptr front header back
96
96 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 2: The queue has nodes. ptr front header back
97
97 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 2: The queue has nodes. ptr front header back
98
98 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 2: The queue has nodes. ptr front header back
99
99 Enqueue (cont.) 30 template 31 void Queue ::enqueue( 32const DataType & element ) 33 { 34Node *ptr = new Node ; 35ptr->info = element; 36back->next = ptr; 37back = ptr; 38 } Case 2: The queue has nodes. ptr front header back
100
100 Dequeue 39 template 40 bool Queue ::dequeue( 41DataType & deqElement ) 42 { 43if ( front == back ) 44return false; Dequeue continued… Returns false if client tries to dequeue an empty queue.
101
101 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header
102
102 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header
103
103 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr
104
104 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr
105
105 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement: passed in by reference
106
106 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
107
107 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
108
108 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
109
109 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
110
110 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
111
111 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr Let’s consider what happens if only one node is left to dequeue.
112
112 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header Let’s consider what happens if only one node is left to dequeue.
113
113 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header
114
114 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr
115
115 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr
116
116 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
117
117 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
118
118 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
119
119 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
120
120 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front back header ptr deqElement:
121
121 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front header ptr deqElement: back
122
122 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front header ptr deqElement: back
123
123 Dequeue (cont.) 45Node *ptr = front->next; 46deqElement = ptr->info; 47front->next = ptr->next; 48if ( back == ptr ) 49back = front; 50delete ptr; 51 52return true; 53 } front header ptr deqElement: back
124
124 Peek 54 template 55 bool Queue ::peek( 56DataType & frontElement ) 57 { 58if ( front == back ) 59return false; 60frontElement = front->next->info; 61return true; 62 }
125
125 isEmpty and makeEmpty 63 template 64 bool Queue ::isEmpty( ) const 65 { 66 return front == back; 67 } 68 69 template 70 void Queue ::makeEmpty( ) 71 { 72 DataType temp; 73while ( dequeue( temp ) ); 74 }
126
126 deepCopy 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback OriginalCopy header
127
127 deepCopy 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback OriginalCopy header
128
128 deepCopy 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback OriginalCopy header front copyptr
129
129 deepCopy 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback OriginalCopy header front copyptr
130
130 deepCopy 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback OriginalCopy header front originalptrcopyptr
131
131 deepCopy 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback OriginalCopy header front originalptrcopyptr deepCopy function continued…
132
132 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
133
133 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
134
134 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
135
135 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
136
136 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
137
137 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
138
138 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
139
139 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
140
140 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
141
141 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
142
142 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
143
143 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
144
144 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
145
145 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
146
146 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
147
147 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
148
148 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
149
149 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
150
150 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
151
151 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
152
152 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
153
153 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
154
154 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
155
155 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
156
156 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
157
157 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
158
158 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
159
159 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
160
160 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr
161
161 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr back
162
162 deepCopy (cont.) 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } frontback OriginalCopy header front originalptrcopyptr back Let’s consider the empty case…
163
163 deepCopy (cont.) 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback OriginalCopy header
164
164 deepCopy (cont.) 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback Original header Copy header front copyptr
165
165 deepCopy (cont.) 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback Original header Copy header front copyptr
166
166 deepCopy (cont.) 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback Original header Copy header front copyptr originalptr
167
167 deepCopy (cont.) 75 template 76 inline void Queue ::deepCopy( 77const Queue & original ) 78 { 79Node *copyptr = front = &header; 80Node *originalptr = original.front; frontback Original header Copy header front copyptr originalptr
168
168 deepCopy (cont.) frontback Original header Copy header front copyptr originalptr 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 }
169
169 deepCopy (cont.) frontback Original header Copy header front copyptr originalptr 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 }
170
170 deepCopy (cont.) frontback Original header Copy header front copyptr originalptr 81while ( originalptr != original.back ) { 82originalptr = originalptr->next; 83copyptr->next = new Node ; 84copyptr = copyptr->next; 85copyptr->info = originalptr->info; 86} 87back = copyptr; 88 } back
171
171 Array Implementation of a Queue Similar to the linked-list queue, there are two data members called front and back, but they are indexes into an Array instead of pointers When enqueuing, the back index is incremented, and when dequeuing, the front index is incremented
172
172 Enqueue / Dequeue 0 1 2 3 4 5 6 7 frontback
173
173 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
174
174 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
175
175 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
176
176 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
177
177 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
178
178 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
179
179 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
180
180 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
181
181 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
182
182 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
183
183 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
184
184 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
185
185 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
186
186 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
187
187 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
188
188 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
189
189 0 1 2 3 4 5 6 7 frontback DEQUEUE Enqueue / Dequeue (cont.)
190
190 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
191
191 0 1 2 3 4 5 6 7 frontback ENQUEUE ? Enqueue / Dequeue (cont.)
192
192 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.) We could double the size of the array here.
193
193 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.) But if we keep doing this, we may have a million elements in the Array, but only a few at the end are used!
194
194 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.) We handle this problem by having the back wrap around to the beginning of the array.
195
195 0 1 2 3 4 5 6 7 frontback ENQUEUE Enqueue / Dequeue (cont.)
196
196 0 1 2 3 4 5 6 7 frontback The front also wraps to the beginning when it reaches the end of the array Enqueue / Dequeue (cont.)
197
197 How Do We Know When the Array is Full? We may still need to double the capacity of the array if it gets filled An array will be full when –back + 1 == front –OR –back + 1 == capacity AND front == 0
198
198 A Full Array 0 1 2 3 4 5 6 7 frontback
199
199 A Full Array 0 1 2 3 4 5 6 7 frontback If the next operation is ENQUEUE, the array capacity will need to be doubled
200
200 The Queue Class Template 1 #include "Array.h" 2 3 template 4 class Queue 5 { 6 public: 7 Queue( ); 8void enqueue( DataType element ); 9bool dequeue( DataType & deqElement ); 10bool peek( DataType & frontElement ); 11bool isEmpty( ) const; 12void makeEmpty( );
201
201 The Queue Class Template (cont.) 13 private: 14Array elements; 15int front; 16int back; 17 }; 18 19 #include "queue.cpp"
202
202 Queue Constructor 1 // queue.cpp 2 template 3 Queue ::Queue( ) 4 : elements( 2 ), front( -1 ), back( -1 ) 5 { 6 }
203
203 Enqueue 7 template 8 void Queue ::enqueue( DataType element ) 9 { 10 if ( back + 1 == front || 11( back == elements.length( ) - 1 && !front ) ) { 12 elements.changeSize( elements.length( ) << 1 ); 13 // if front end was last part of array, readjust 14 if ( back < front ) { 15int i = elements.length( ) - 1; 16for ( int j = ((i + 1) >> 1) - 1; j >= front; i--, j-- ) 17elements[ i ] = elements[ j ]; 18front = i + 1; 19} 20} Enqueue continued…
204
204 Enqueue (cont.) 21if ( back == -1 ) // queue is empty 22front = 0; 23back = (back == elements.length( ) - 1)? 240 : back + 1; 25elements[ back ] = element; 26 }
205
205 Dequeue 27 template 28 bool Queue ::dequeue( 29DataType & deqElement ) 30 { 31if (front == -1 ) 32return false; Dequeue continued…
206
206 Dequeue (cont.) 33deqElement = elements[ front ]; 34if ( front == back ) // only one element was in queue 35front = back = -1; 36else 37front = (front == elements.length( ) - 1)? 380 : front + 1; Dequeue continued…
207
207 Dequeue (cont.) 39// try to reduce the size of the array 40int trysize = elements.length( ); 41int numElements = (front <= back)? 42back - front + 1 : back + trysize - front + 1; 43while ( ( numElements > 2 ) && trysize > 2 ) 44trysize >>= 1; Dequeue continued…
208
208 Dequeue (cont.) 45if ( trysize < elements.length( ) ) { 46// readjust so we won't lose elements when 47// shrinking the array size 48int i, j; 49if ( front > back ) { If true, we can try to change the size of the array… The code for the “front > back” case is shown next…
209
209 Dequeue (cont.) 50 for ( i = trysize - 1, j = elements.length( ) - 1; j >= front; i--, j-- ) 51elements[ i ] = elements[ j ]; 52 front = i + 1; 53 try { 54elements.changeSize( trysize ); 55} 56 catch( … ) { 57 for ( i = elements.length( ) - 1, j = trysize - 1; j >= front; i--, j-- ) 58 elements[ i ] = elements[ j ]; 59 front = i + 1; 60 } If we can’t change the size, we’ll have to undo the realignment on lines 50-52.
210
210 Dequeue (cont.) 61return true; 62} 63else if ( front = trysize ) { 64for ( i = 0, j = front; j <= back; i++, j++ ) 65elements[ i ] = elements[ j ]; 66front = 0; 67back = i - 1; 68} We need to return for the “front > back” case We won’t need to undo this realignment if we can’t change the size. We’re ready for the changeSize attempt…
211
211 Dequeue (cont.) 69try { 70elements.changeSize( trysize ); 71 } 72catch( … ) { } 73} 74 75return true; 76 } This changeSize attempt handles the “front = trysize” case AND the case where no realignment is necessary: “front <= back && back < trysize”
212
212 Peek 77 template 78 bool Queue ::peek( 79DataType & frontElement ) 80 { 81if (front == -1 ) 82return false; 83frontElement = elements[ front ]; 84return true; 85 }
213
213 isEmpty 86 template 87 bool Queue ::isEmpty( ) const 88 { 89return front == -1; 90 }
214
214 makeEmpty 91 template 92 void Queue ::makeEmpty( ) 93 { 94front = back = -1; 95try { 96elements.changeSize( 2 ); 97} 98catch( … ) { } 99 }
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.