Upload
dante-eubanks
View
219
Download
1
Embed Size (px)
Citation preview
2
Objectives
You will be able to: Describe a stack as an ADT. Build a dynamic-array-based implementation of
stacks. Build a linked-list implementation of stacks.
3
Stack
A stack is a last-in-first-out (LIFO) data structure.
Basic Operations:
Add an item Referred to as pushing it onto the stack
Remove an item Referred to as popping it from the stack
4
Stack as an ADT
Definition: An ordered collection of data items. Can be accessed only at one end, the top
Operations: Construct an empty stack Check if a stack is empty Push: Add an element to the top Pop: Remove the top element Top: Retrieve the top element
5
Example
Consider a program to convert decimal numbers to binary
Repeatedly Divide the decimal value by 2 Push the remainder onto a stack
Continue until quotient is 0
Pop values off the stack and output
6
A Simple Stack Template
Store stack elements in a dynamically allocated array.
Member variable identifies top of stack.
Throw an exception if client attempts to push an element when stack is full or pop an element when stack is empty.
7
Create Project
Create a new empty C++ Console Application Project Simple_Stack_Demo
Add stack.h Add stack_test.cpp Code is available at: http://www.cse.usf.edu/~turnerr/Data_Structures/Down
loads/2011_02_07_Stacks/
stack.h#pragma once
#include <iostream>
#include <cassert>
template <class T>
class Stack
{
public:
...
private:
T* data; // Dynamically allocated array
int size; // Number of elements
int top; // Index of element at top of stack
// -1 when stack is empty
};
stack.h#pragma once
#include <iostream>
#include <cassert>
template <class T>
class Stack
{
public:
Stack(int capacity = 1000);
~Stack();
bool IsEmpty() const {return top == -1;};
bool IsFull() const {return top == size-1;};
// Add a value to the top of the stack.
void Push(const T& value);
// Remove and return value at top of stack.
T Pop();
// Retrieve value at top of stack without removing it.
T Top() const;
// Display stack contents.
void Display(std::ostream& out) const;
10
Constructor and Destructor
template <class T>
Stack<T>::Stack(int capacity): top(-1), size(capacity)
{
data = new T[capacity];
assert (data != 0);
}
template <class T>
Stack<T>::~Stack()
{
delete[] data;
}
11
Push()
template <class T>
void Stack<T>::Push(const T& value)
{
if (this->IsFull())
{
throw "Stack overflow";
}
data[++top] = value;
}
12
Pop()
template <class T>
T Stack<T>::Pop()
{
if (this->IsEmpty())
{
throw "Pop called for empty stack";
}
return data[top--];
}
13
Top()
template <class T>
T Stack<T>::Top() const
{
if (this->IsEmpty())
{
throw "Top of empty stack requested";
}
return (data[top]);
}
14
stack_test.cpp
#include <iostream>
#include "Stack.h"
#include <assert.h>
using namespace std;
const int STACK_CAPACITY = 10;
int main()
{
Stack<int> s(STACK_CAPACITY);
assert (s.IsEmpty());
cout << "Newly created stack is empty\n";
printf ("Pushing 0 - %d \n", STACK_CAPACITY - 1);
for (int i = 0; i < STACK_CAPACITY; ++i)
{
s.Push(i);
}
cout << "Initial stack:\n";
s.Display(cout);
15
stack_test.cpp
assert(!s.IsEmpty());
cout << "Now the stack is not empty\n";
cout << "Adding one more element, which should cause overflow. " << endl;
try
{
s.Push(1);
cout << "ERROR\n"; // Should have thrown exception
}
catch (const char* msg)
{
cout << "Attempt to overfill stack threw exception as expected\n";
cout << "Message: " << msg << endl;
}
cout << "Stack should be unchanged\n" << endl;
s.Display(cout);
16
stack_test.cpp
cout << "Now poping elements off the stack\n";
while (!s.IsEmpty())
{
int top = s.Top();
cout << "Stack top: " << top << endl;
int next_item = s.Pop();
assert (next_item == top);
}
cout << "Stack is now empty\n";
cout << "Getting top of empty stack. This should fail\n";
try
{
int x = s.Top();
cout << "ERROR\n"; // Should have thrown exception
}
catch (const char* msg)
{
cout << "Attempt to get top of empty stack threw exception as expected\n";
cout << "Message: " << msg << endl;
}
17
stack_test.cpp
cout << "Doing one more pop. This should fail\n";
try
{
s.Pop();
cout << "ERROR\n"; // Should have thrown exception
cin.get();
}
catch (char* msg)
{
cout << "Attempt to pop empty stack threw exception as expected\n";
cout << "Message: " << msg << endl;
}
18
stack_test.cpp
cout << "Testing dynamic allocation\n";
Stack<int>* s2 = new Stack<int>(STACK_CAPACITY);
assert(s2 != 0);
cout << "Allocation was successful\n";
cout << "Testing delete\n";
delete(s2);
s2 = 0;
cout << "Delete was successful\n";
cout << "Test complete. Press Enter to exit." << endl;
cin.get(); // Hold window open
return 0;
}
21
An Application: Decimal to Binary Conversion
stack_demo.cpp
/*--------------------------------------------------------------
This program uses a stack to convert the base-ten representation
of a positive integer entered as input to base two, which is
then output.
---------------------------------------------------------------------*/
#include <iostream>
#include "Stack.h"
using namespace std;
int main()
{
int number; // the number to be converted
int remainder; // remainder when number is divided by 2
Stack<int> remainders; // stack of remainders
cout << "This program displays the binary representation of integers\n";
cout << "that you specify. Enter 0 to end program\n\n";
22
stack_demo.cpp
while (true)
{
cout << "Enter positive integer to convert: ";
cin >> number;
if (number <= 0)
{
break;
}
while (number != 0)
{
remainder = number % 2;
remainders.Push(remainder);
number /= 2;
}
cout << "Base-two representation: ";
while (!remainders.IsEmpty() )
{
remainder = remainders.Pop();
cout << remainder;
}
cout << endl << endl;
}
25
Allocation Failure
Let’s see if we can force an allocation failure and see what happens.
Stack<int> remainders(INT_MAX); // stack of remainders
26
stack_test.cpp
#include <iostream>
#include "Stack.h"
#include <cassert>
using namespace std;
int main()
{
try
{
Stack* s = new Stack<int>(INT_MAX);
assert(s != 0);
cout << "Allocation was successful\n";
}
catch (bad_alloc& ba)
{
cout << "Caught Bad Allocation exception\n";
cout << ba.what() << endl;
}
cout << "Test complete. Press enter to exit.\n";
cin.get(); // Hold window open
return 0;
}