Data Structures: Stacks Queues
-
Upload
clinton-burnett -
Category
Documents
-
view
39 -
download
1
description
Transcript of Data Structures: Stacks Queues
Data Structures: StacksQueues
1
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
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
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
Class Interface Diagram (static array)
StackType class
StackType
MakeEmpty
Pop
Push
IsFull
IsEmpty
Private data:
top
[MAX_ITEMS-1] . . .
[ 2 ]
[ 1 ]
items [ 0 ]
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
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
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
char letter = ‘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 Codeletter ‘V’
11
char letter = ‘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 Codeletter ‘V’
Private data:
top -1
[MAX_ITEMS-1] . . .
[ 2 ]
[ 1 ]
items [ 0 ]
12
char letter = ‘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 Codeletter ‘V’
Private data:
top 0
[MAX_ITEMS-1] . . .
[ 2 ]
[ 1 ]
items [ 0 ] ‘V’
13
char letter = ‘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 Codeletter ‘V’
Private data:
top 1
[MAX_ITEMS-1] . . .
[ 2 ]
[ 1 ] ‘C’
items [ 0 ] ‘V’
14
char letter = ‘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 Codeletter ‘V’
Private data:
top 2
[MAX_ITEMS-1] . . .
[ 2 ] ‘S’
[ 1 ] ‘C’
items [ 0 ] ‘V’
15
char letter = ‘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 Codeletter ‘V’
Private data:
top 2
[MAX_ITEMS-1] . . .
[ 2 ] ‘S’
[ 1 ] ‘C’
items [ 0 ] ‘V’
16
char letter = ‘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 Codeletter ‘S’
Private data:
top 1
[MAX_ITEMS-1] . . .
[ 2 ] ‘S’
[ 1 ] ‘C’
items [ 0 ] ‘V’
17
char letter = ‘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 Codeletter ‘S’
Private data:
top 2
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
18
char letter = ‘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 Codeletter ‘S’
Private data:
top 2
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
19
char letter = ‘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 Codeletter ‘K’
Private data:
top 1
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
20
char letter = ‘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 Codeletter ‘K’
Private data:
top 1
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
21
char letter = ‘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 Codeletter ‘C’
Private data:
top 0
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
22
char letter = ‘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 Codeletter ‘C’
Private data:
top 0
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
23
char letter = ‘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 Codeletter ‘V’
Private data:
top -1
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
24
char letter = ‘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 Traceletter ‘V’
Private data:
top -1
[MAX_ITEMS-1] . . .
[ 2 ] ‘K’
[ 1 ] ‘C’
items [ 0 ] ‘V’
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
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
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 leakitems = new char[capacity];top = otherStack.top;
for(int i=0; i<=top; i++)items[i] = otherStack.items[i];
}
27
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
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 factorchar *temp = new char[capacity]; //allocate new stack arrayfor( int i=0; i<=top; i++ ) //copy items to new stack array
temp[i] = items[i];delete [] items; //deallocate old stack arrayitems = temp; //redirect pointer to new stack array}
//perform push as usualtop++;items[top] = newItem;
}
29
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
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
class StackType
StackType
MakeEmpty
Pop
Push
IsFull
IsEmpty Private data:
topPtr
~StackType
‘C’ ‘V’
33
Tracing Client Codeletter ‘V’
char letter = ‘V’;
StackType myStack;
myStack.Push(letter);
myStack.Push(‘C’);
myStack.Push(‘S’);
if ( !myStack.IsEmpty( ) ) letter = myStack.Pop( );
myStack.Push(‘K’);
34
Tracing Client Codeletter ‘V’
char letter = ‘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
Tracing Client Codeletter
char letter = ‘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’
‘V’
36
Tracing Client Codeletter
char letter = ‘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
Tracing Client Codeletter
char letter = ‘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
Tracing Client Codeletter
char letter = ‘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
Tracing Client Codeletter
char letter = ‘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
Tracing Client Codeletter
char letter = ‘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
Modifying a Linked List Classfor 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
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
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
void Stack::Push ( /* in */ char item ){InsertFront(item);}
char Stack::Pop ( ){return DeleteFront();}
44
Alternate Implementations
45
The C++ stack Class• Part of Standard Template Library
• Must include stack library
#include <stack>
• Declare the stack
stack <type> stack-name;
• E.g.
stack <string> nameStack;
stack <char> s;
• Use to compare/test YOUR stack classes…
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
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
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
Examples of Stack Syntax Checking
Sample statements:
{x = (a*(b+(c[3])))}
{x=(a*(b+c[2])})
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
Example Queues
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
Queues as Arrays
• Implementations are very similar to stack
• Only differ in where the data is accessed
– we will analyze EnQueue and DeQueue
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
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
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
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
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
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
class QueType
QueType
~QueType
Enqueue
Dequeue . . .
Private Data:
qFront
qRear
‘C’ ‘Z’ ‘T’
62
Modifying Linked List Classfor 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
// SPECIFICATION FILE // DYNAMIC-LINKED QUEUEclass 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
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
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
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
The C++ queue Class• Part of Standard Template Library
• Must include queue library
#include <queue>
• Declare the stack
queue <type> queue-name;
• E.g.
queue <string> customers;
queue <float> readings;
• Use to compare/test YOUR queue classes…
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
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
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