Download presentation
Presentation is loading. Please wait.
Published byHector Carter Modified over 9 years ago
1
Data Structures: Stacks Queues 1
2
2 Stack ADT: What is a Stack? a stack is a varying-length, collection of homogeneous elements Insertion and Deletion only occurs at the front (or top) of the stack. –Push and Pop –Last In First Out (LIFO) Structure How might we implement a stack?
3
3
4
4 Array Stack Implementation First element on can go in first array position, the second in the second position, etc. The top of the stack is the index of the last element added to the stack Stack elements are stored in an array Stack element is accessed only through top To keep track of the top position use a variable called top
5
5 Array Stack Implementation Because a stack is homogeneous you can use an array to implement a stack Can use static array if maximum size known in advance Can dynamically allocate array to specify size of the array Data movement more efficient than array lists due to no access to middle elements
6
6 Class Interface Diagram (static array) StackType class StackType MakeEmpty Pop Push IsFull IsEmpty Private data: top [MAX_ITEMS-1]. [ 2 ] [ 1 ] items [ 0 ]
7
7 const int MAX_ITEMS = 50; class StackType { public: StackType( ); // Default constructor. // POST: Stack is created and empty. void MakeEmpty( ); // PRE: None. // POST: Stack is empty. bool IsEmpty( ) const; // PRE: Stack has been initialized. // POST: Function value = (stack is empty) bool IsFull( ) const; // PRE: Stack has been initialized. // POST: Function value = (stack is full) void Push( char newItem ); // PRE: Stack has been initialized and is not full. // POST: newItem is at the top of the stack. char Pop( ); // PRE: Stack has been initialized and is not empty // POST: top element has been removed from the stack //returns a copy of removed element private: int top; char items[MAX_ITEMS];// static array of characters };
8
8 StackType::StackType( ) // Default Constructor { top = -1; } void StackType::MakeEmpty( ) { top = -1; } bool StackType::IsEmpty( ) const { return ( top == -1 ); } bool StackType::IsFull( ) const { return ( top == MAX_ITEMS-1 ); } 8
9
9 void StackType::Push ( char newItem ) //------------------------------------------------------ // PRE: Stack has been initialized and is not full // POST: newItem is at the top of the stack. //------------------------------------------------------ { top++; items[top] = newItem; } char StackType::Pop ( ) //------------------------------------------------------ // PRE: Stack has been initialized and is not empty // POST: Top element has been removed from stack. // returns a copy of removed element. //------------------------------------------------------ { char value = items[top]; top--; return value; } 9
10
10 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘V’
11
11 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘V’ Private data: top -1 [ MAX_ITEMS-1 ]. [ 2 ] [ 1 ] items [ 0 ]
12
12 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘V’ Private data: top 0 [ MAX_ITEMS-1 ]. [ 2 ] [ 1 ] items [ 0 ] ‘V’
13
13 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘V’ Private data: top 1 [ MAX_ITEMS-1 ]. [ 2 ] [ 1 ] ‘C’ items [ 0 ] ‘V’
14
14 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘V’ Private data: top 2 [ MAX_ITEMS-1 ]. [ 2 ] ‘S’ [ 1 ] ‘C’ items [ 0 ] ‘V’
15
15 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘V’ Private data: top 2 [ MAX_ITEMS-1 ]. [ 2 ] ‘S’ [ 1 ] ‘C’ items [ 0 ] ‘V’
16
16 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘S’ Private data: top 1 [ MAX_ITEMS-1 ]. [ 2 ] ‘S’ [ 1 ] ‘C’ items [ 0 ] ‘V’
17
17 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘S’ Private data: top 2 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
18
18 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘S’ Private data: top 2 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
19
19 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘K’ Private data: top 1 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
20
20 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘K’ Private data: top 1 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
21
21 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘C’ Private data: top 0 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
22
22 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘C’ Private data: top 0 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
23
23 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Tracing Client Code letter ‘V’ Private data: top -1 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
24
24 charletter = ‘V’; StackType charStack; charStack.Push(letter); charStack.Push(‘C’); charStack.Push(‘S’); if ( !charStack.IsEmpty( )) letter = charStack.Pop(); charStack.Push(‘K’); while (!charStack.IsEmpty( )) letter = charStack.Pop(); Test Fails – End Trace letter ‘V’ Private data: top -1 [ MAX_ITEMS-1 ]. [ 2 ] ‘K’ [ 1 ] ‘C’ items [ 0 ] ‘V’
25
25 A Dynamic Array Class Use dynamic array to hold items Store capacity and top in private data Resize array to accommodate unlimited size –done in Push member –data movement in resize is costly… Provide parameterized constructor, copy constructor, and destructor Provide same functionality so client code is same
26
26 class StackType { public: StackType( ); StackType( int sizeIn ); // Parameterized constructor // POST: Stack is allocated and empty StackType( StackType& otherStack ); // Copy constructor // POST: Stack is a deep copy of target stack ~StackType( ); // Destructor // POST: Stack is deallocated void MakeEmpty( ); bool IsEmpty( ) const; bool IsFull( ) const; void Push( char newItem ); char Pop( ); private: int top, capacity; char *items;// dynamicic array of characters };
27
27 StackType::StackType( ) // Default Constructor { capacity = 50; items = new char[capacity]; top = -1; } StackType:: StackType( int sizeIn ) // Parameterized constructor { capacity = sizeIn; items = new char[capacity]; top = -1; } StackType:: StackType( StackType& otherStack ) //Copy Constructor { capacity = otherStack.capacity; Delete [] items; //prevent memory leak items = new char[capacity]; top = otherStack.top; for(int i=0; i<=top; i++) items[i] = otherStack.items[i]; } 27
28
28 StackType::~StackType( ) // Destructor { delete [] items; } void StackType::MakeEmpty( ) { top = -1; } bool StackType::IsEmpty( ) const { return ( top == -1 ); } bool StackType::IsFull( ) const { return false; //stack cannot get full due to resizing... } 28
29
29 void StackType::Push ( char newItem ) //------------------------------------------------------ // PRE: Stack has been initialized // POST: newItem is at the top of the stack. // stack resized if necessary //------------------------------------------------------ { if( top == capacity-1 ) //resize necessary { capacity = capacity + 50; //you can change resize factor char *temp = new char[capacity]; //allocate new stack array for( int i=0; i<=top; i++ ) //copy items to new stack array temp[i] = items[i]; delete [] items; //deallocate old stack array items = temp; //redirect pointer to new stack array } //perform push as usual top++; items[top] = newItem; } 29
30
30 char StackType::Pop ( ) //------------------------------------------------------ // PRE: Stack has been initialized and is not empty // POST: Top element has been removed from stack. // returns a copy of removed element. //------------------------------------------------------ { char value = items[top]; top--; return value; } 30
31
31 Linked Implementation of Stacks Static array only allows fixed number of elements Dynamic arrays can resize, but inefficient Linked nodes can dynamically organize data In a linked representation, there is a pointer to top element in stack
32
32 class StackType StackType MakeEmpty Pop Push IsFull IsEmpty Private data: topPtr ~StackType ‘C’ ‘V’
33
33 Tracing Client Code letter ‘V’ charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’);
34
34 Tracing Client Code letter ‘V’ charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’); Private data: topPtr NULL
35
35 Tracing Client Code letter charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’); Private data: topPtr ‘V’
36
36 Tracing Client Code letter charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’); Private data: topPtr ‘C’ ‘V’ ‘V’
37
37 Tracing Client Code letter charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’); Private data: topPtr ‘S’ ‘C’ ‘V’ ‘V’
38
38 Tracing Client Code letter charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’); Private data: topPtr ‘S’ ‘C’ ‘V’ ‘V’
39
39 Tracing Client Code letter charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’); Private data: topPtr ‘C’ ‘V’ ‘S’
40
40 Tracing Client Code letter charletter = ‘V’; StackType myStack; myStack.Push(letter); myStack.Push(‘C’); myStack.Push(‘S’); if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( ); myStack.Push(‘K’); Private data: topPtr ‘K’ ‘C’ ‘V’ ‘S’
41
41 Modifying a Linked List Class for Stack Functionality How does the stack ADT differ from the list ADT? –Where are the items accessed? –“Data Flow Characteristics” How might we change features of the linked list class so that it fulfills the stack ADT? –Add Push and Pop –Remove Insert/Delete
42
42 void Stack::Push ( /* in */ char item ) // Adds item to the top of the stack. { NodeType* location; location = new NodeType; location->info = item; location->next = head; head = location; } NOTE: This is the same code as the existing InsertFront member... 42 Implementing Push
43
43 char Stack::Pop ( ) // removes item at top of the stack and returns it { NodeType* tempPtr; char item = head->info; tempPtr = head; head = head->next; delete tempPtr; return item; } NOTE: This is the same code as the existing DeleteFront member... 43 Implementing Pop
44
44 void Stack::Push ( /* in */ char item ) { InsertFront(item); } char Stack::Pop ( ) { return DeleteFront(); } 44 Alternate Implementations
45
45 The C++ stack Class Part of Standard Template Library Must include stack library #include Declare the stack stack stack-name; E.g. stack nameStack; stack s; Use to compare/test YOUR stack classes…
46
46 Application of Stacks: POSTFIX EXPRESSIONS CALCULATOR In infix notation: –Operator is written between the operands For example, a+b Lukasiewicz discovered parentheses can be omitted if operators are written –Before operands (prefix or Polish notation; for example, + a b) –After the operands (suffix, postfix, or reverse Polish notation; for example, a b +) Can use a stack to evaluate postfix
47
47 Postfix Example The postfix method uses a stack. To process the infix expression 5 – (3 + 1) * 2 In postfix, it would be represented by 5 3 1 + 2 * - A postfix machine processes an expression using the algorithm: Push values If an operator: pop operand 2 pop operand 1 perform the operation operand 1 operator operand 2 push the result
48
48 Stack application: syntax checking A compiler uses a stack to check for correct syntax of tokens that come in pairs: () [] {} The logic: Left token: push it on a stack Right token: Pop off of stack For correct syntax, there must be a matching left token on the stack when a pop occurs, and at the end of the statement, the stack must be empty
49
49 Examples of Stack Syntax Checking Sample statements: {x = (a*(b+(c[3])))} {x=(a*(b+c[2])})
50
50 Queue ADT: What is a Queue? a queue is a varying-length, collection of homogeneous elements Insertion only occurs at the rear of the queue, Deletion only occurs at the front. –Enqueue and Dequeue –First In First Out (FIFO) Structure How might we implement a queue?
51
51 Example Queues
52
52 Queues as Arrays You need these data members: –An array to store the queue elements static or dynamic –queueFront and queueRear: keep track of first and last elements in the array –maxQueueSize: specify maximum size declare as constant if using static array –count: keep track of how many elements are in the queue at a given time (optional)
53
53 Queues as Arrays Implementations are very similar to stack Only differ in where the data is accessed –we will analyze EnQueue and DeQueue
54
54 void QueType::EnQueue( char newItem ) // Adds newItem to the rear of dynamic array queue. // Pre: Queue has been initialized. // Queue is not full // Post: newItem is at rear of queue. { qRear = (qRear+1) % maxQue; items[qRear] = newItem; count++; } 54
55
55 char QueType::DeQueue( ) // Removes element from dynamic array queue // and returns it in item. // Pre: Queue has been initialized. // Queue is not empty. // Post: Front element has been removed from queue. // item is a copy of removed element. { char value = items[qFront]; qFront = (qFront+1) % maxQue; count--; return value; } 55
56
56 Circular Queue The previous implementation of a queue by an array can be called a circular queue: The first array position immediately follows the last array position
57
57
58
58 Alternative Queue Array Scheme If there is room in the front of the array (elements have been dequeued), when rear gets to last array position –Slide all queue elements toward first array position This solution is ok if queue size is very small –Otherwise, program may execute slowly
59
59 Implementing a Linked Node Queue Static array only allows fixed number of elements Dynamic arrays can resize, but inefficient Linked lists can dynamically organize data
60
60 Implementing a Linked Node Queue Much like a list and a stack, there is a pointer to front element in queue –Old Items DeQueued at Front Different from list and stack, there is a pointer to rear element in queue –New Items EnQueued at Rear
61
61 class QueType QueType ~QueType Enqueue Dequeue. Private Data: qFront qRear ‘C’‘Z’ ‘T’
62
62 Modifying Linked List Class for Stack Functionality How does the stack ADT differ from the list ADT? –Where are the items accessed? –“Data Flow Characteristics” How might we change features of the linked list class so that it satisfies the queue ADT? –Add Enqueue and Dequeue –Add a Rear Pointer and Node Counter –Remove Insert and Delete
63
63 // SPECIFICATION FILE // DYNAMIC-LINKED QUEUE class LinkedQ { public : bool IsEmpty ( ) const ; void Print ( ) const ; void EnQueue(/* in */ char item); char DeQueue( ); LinkedQ( ) ;// Constructor ~ LinkedQ ( ) ;// Destructor LinkedQ ( const LinkedQ & otherQ ) ; // Copy-constructor private : NodeType* head; NodeType* tail; int nodeCount; } ; 63
64
64 void LinkedQ::EnQueue ( /* in */ char newItem ) // Adds item to the rear of the queue { NodeType* ptr; ptr = new NodeType; ptr->info = newItem; ptr->next = NULL; if ( tail == NULL ) head = ptr; else tail->next = ptr; tail = ptr; nodeCount--; } 64 Implementing EnQueue
65
65 char LinkedQ::DeQueue ( ) // removes item at front of the queue and returns it { NodeType* tempPtr; tempPtr = head; char item = head->info; head = head->next; if ( head == NULL ) tail = NULL; delete tempPtr; nodeCount++; return item; } NOTE: This is nearly the same code as the existing DeleteFront member only we are now taking care of the tail pointer and code count... 65 Implementing DeQueue
66
66 Additional Modifications Modify all insert and delete algorithms to maintain the tail pointer and the node counter IsFull is not necessary since Dynamic Linked Nodes never fill up, implement it if necessary to always return false Add the getSize member to return the node counter
67
67 The C++ queue Class Part of Standard Template Library Must include queue library #include Declare the stack queue queue-name; E.g. queue customers; queue readings; Use to compare/test YOUR queue classes…
68
68 Application of Queues Simulation: Queues are used extensively in the real world (every time you or anything else waits in a line) Queuing requests for a service: For example, Internet messages arriving at a communications server, processes requesting CPU time
69
69 Summary Stack: items are added and deleted from one end Last In First Out (LIFO) data structure Stack operations: push, pop, initialize, destroy, check for empty/full stack Can be implemented as array or linked list Middle elements should not be accessed Postfix notation: no parentheses for operator precedence –Operators come after operands
70
70 Summary Queue: items are added at one end and removed from the other end First In First Out (FIFO) data structure Queue operations: enqueue, dequeue, initialize, destroy, check if queue is empty/full Can be implemented as array or linked list Middle elements should not be accessed Restricted versions of arrays and linked lists
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.