#ifndef ARRAYSTACK_STACK_H
#define ARRAYSTACK_STACK_H
#include <algorithm>
template<class T>
class stack
{
public:
virtual ~stack() {}
virtual bool empty() const = 0;
virtual int size() const = 0;
virtual T& top() = 0;
virtual void pop() const = 0;
virtual void push(const T& theElement) = 0;
};
template <class T>
void changeLength1D(T* &a, int oldLength, int newLength)
{
if(newLength < 0)
{
std::cout << "The new Length must bigger than 0"<<std::endl;
return;
}
T* temp = new T[newLength];
int number = std::min(oldLength, newLength);
std::copy(a, a+number, temp);
delete [] a;
a = temp;
}
#endif
#ifndef ARRAYSTACK_ARRAYSTACK_H
#define ARRAYSTACK_ARRAYSTACK_H
#include "stack.h"
#include <exception>
#include <string>
class Err : public std::exception
{
public:
Err(std::string ss) {str = ss;}
virtual const char* what() const throw()
{
return str.c_str();
}
private:
std::string str;
};
template<class T>
class arrayStack
{
template<class U>
friend std::ostream & operator << (std::ostream &os, arrayStack<U> &stack);
public:
arrayStack(int initialCapacity = 10);
~arrayStack() {delete [] stack; }
bool empty() const { return stackTop == -1;}
int size() const {return stackTop+1;}
T& top();
void pop()
{
if (stackTop == -1)
return;
stack[stackTop--].~T();
}
void push(const T& theElement);
void input();
void devide(arrayStack<T> &firstStack, arrayStack<T> &secondStack);
void meld(arrayStack<T> &secondStack);
private:
int stackTop;
int arrayLength;
T* stack;
};
template<class T>
arrayStack<T>::arrayStack(int initialCapacity)
{
if (initialCapacity < 1)
{
std::cout << "the Initial capacity is " << initialCapacity << std::endl;
return;
}
arrayLength = initialCapacity;
stack = new T[initialCapacity];
stackTop = -1;
}
template<class T>
void arrayStack<T>::push(const T &theElement)
{
if (stackTop == arrayLength - 1)
{
changeLength1D(stack, arrayLength, 2 * arrayLength);
arrayLength = 2 * arrayLength;
}
stack[++stackTop] = theElement;
}
template<class T>
void arrayStack<T>::input()
{
T element;
std::cout << "Input the data!" << std::endl;
std::cout << "Ctrl+D stop the input!" << std::endl;
while (std::cin >> element)
{
push(element);
}
}
template<class T>
T &arrayStack<T>::top()
{
if (stackTop == -1)
throw Err("There is no data in stack!");
return stack[stackTop];
}
template<class T>
void arrayStack<T>::devide(arrayStack<T> &firstStack, arrayStack<T> &secondStack)
{
if (empty())
{
std::cerr << "The stack is empty, can't be devided!" << std::endl;
return;
}
int middleLength = (stackTop+1)/2;
if (firstStack.arrayLength < middleLength)
changeLength1D(firstStack.stack, firstStack.arrayLength, middleLength);
if (secondStack.arrayLength < middleLength)
changeLength1D(secondStack.stack, secondStack.arrayLength, middleLength);
std::copy(stack, stack+middleLength+1, firstStack.stack);
firstStack.stackTop = middleLength - 1;
secondStack.stackTop = stackTop - middleLength;
std::copy(stack+middleLength, stack + stackTop + 1, secondStack.stack);
}
template<class U>
std::ostream &operator<<(std::ostream &os, arrayStack<U> &stack)
{
for (int i=0; i <= stack.stackTop; i++)
os << stack.stack[i] << " ";
return os;
}
template<class T>
void arrayStack<T>::meld(arrayStack<T> &secondStack)
{
int newTop = stackTop + secondStack.stackTop + 2;
if (newTop > arrayLength)
{
changeLength1D(stack, stackTop, newTop);
arrayLength = newTop;
}
std::copy(secondStack.stack, secondStack.stack + secondStack.stackTop + 1, stack + stackTop + 1);
stackTop = newTop - 1;
}
#endif
#ifndef LINKEDSTACK_LINKEDSTACK_H
#define LINKEDSTACK_LINKEDSTACK_H
#include "stack.h"
#include <exception>
class Err : public std::exception
{
public:
Err(std::string ss) {str = ss;}
virtual const char* what() const throw()
{
return str.c_str();
}
private:
std::string str;
};
template<class T>
struct chainNode
{
T element;
chainNode<T>* next;
chainNode() {}
chainNode(const T& element) {this->element=element;}
chainNode(const T& element, chainNode<T>* next) {this->element=element;this->next=next;}
};
template<class T>
class linkedStack : public stack<T>
{
template<class U>
friend std::ostream &operator<<(std::ostream& os, linkedStack<U>& x);
public:
linkedStack();
~linkedStack();
bool empty() const { return stackSize == 0;}
int size() const {return stackSize;}
T& top();
void pop();
void push(const T& theElement);
void pushNode(chainNode<T>* theNode);
chainNode<T>* popNode();
private:
chainNode<T>* stackTop;
int stackSize;
};
template<class T>
linkedStack<T>::linkedStack()
{
stackTop = NULL;
stackSize = 0;
}
template<class T>
linkedStack<T>::~linkedStack()
{
chainNode<T>* deleteNode;
while (stackSize-- > 0)
{
deleteNode = stackTop;
stackTop = stackTop->next;
delete deleteNode;
}
}
template<class T>
void linkedStack<T>::pop()
{
if (stackSize != 0)
{
chainNode<T>* deleteNode = stackTop;
stackTop = stackTop->next;
delete deleteNode;
stackSize--;
}
else
throw Err("The stack is empty, can't pop!");
}
template<class T>
T &linkedStack<T>::top()
{
if (stackSize == 0)
throw Err("The stack is empty, has no top element!");
return stackTop->element;
}
template<class T>
void linkedStack<T>::push(const T &theElement)
{
if (stackSize == 0)
{
stackTop = new chainNode<T>(theElement, NULL);
stackSize++;
}
else
{
stackTop = new chainNode<T>(theElement, stackTop);
stackSize++;
}
}
template<class T>
void linkedStack<T>::pushNode(chainNode<T> *theNode)
{
theNode->next = stackTop;
stackTop = theNode;
stackSize++;
}
template<class T>
chainNode<T> *linkedStack<T>::popNode()
{
if (stackSize == 0)
throw Err("The stack is empty, can't pop Node!");
chainNode<T>* popnode = stackTop;
stackTop = stackTop->next;
popnode->next = NULL;
stackSize--;
return popnode;
}
template<class U>
std::ostream &operator<<(std::ostream &os, linkedStack<U> &x)
{
for (chainNode<U> *firstNode = x.stackTop;firstNode != NULL;firstNode = firstNode->next)
os << firstNode->element << " ";
return os;
}
#endif