数据结构—栈
栈的定义
栈是限定仅在表尾(栈顶)进行插入(也称入栈或压栈)和删除(也称出栈或弹栈)操作的线性表,是一个后进先出(last-in-first-out, LIFO)的数据结构,简称LIFO
结构。
我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。
栈的抽象数据类型
抽象数据类型 stack
{
实例
线性表:一断称为底,另一端称为顶
操作
empty():// 栈为空时返回true,否则返回false
size():// 返回栈中元素的个数
top(): // 返回栈顶元素
pop():// 删除栈顶元素
push(x):// 将元素x压入栈顶
}
栈的抽象类
template<class T>
class stack
{
public:
virtual ~stack() {}
virtual bool empty() const = 0; // 返回为true,当且仅当栈为空
virtual int size() const = 0; // 返回栈中元素个数
virtual void pop() = 0; // 删除栈顶元素
virtual void push(const T& theElement) = 0; // 将元素theElement压入栈顶
};
栈的数组描述
因为栈是一种插入和删除操作都被限制在一端进行的线性表,所以可以使用任何一种线性表的描述方法。
template<class T>
class arrayStack : public stack<T>
{
public:
arrayStack(int initialCapacity = 10);
~arrayStack() { delete[] stack; }
bool empty() const { return stackTop == -1; }
int size() const { return stackTop + 1; }
T& top()
{
if (stackTop == -1)
throw stackEmpty();
return stack[stackTop];
}
void pop()
{
if (stackTop == -1)
throw stackEmpty();
stack[stackTop--].~T(); // T的析构函数
}
void push(const T& theElement);
private:
void stackEmpty()
{
cout << "stack is empty\n";
}
int stackTop; // 当前栈顶
int arrayLength; // 栈容量
T* stack; // 元素数组
};
template<class T>
arrayStack<T>::arrayStack(int initialCapacity)
{// 构造函数
if (initialCapacity < 1)
{
ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
throw illegalParameterValue(s.str());
}
arrayLength = initialCapacity;
stack = new T[arrayLength];
stackTop = -1;
}
template<class T>
void arrayStack<T>::push(const T& theElement)
{// 将元素theElement压入栈
if (stackTop == arrayLength - 1)
{// 空间已满,容量加倍
changeLength1D(stack, arrayLength, 2 * arrayLength);
arrayLength *= 2;
}
// 在栈顶插入
stack[++stackTop] = theElement;
}
栈的链表描述
当用链表描述栈时,我们必须确定用链表的哪一端表示栈顶。我们这里选择链表的左端作为栈顶。
template<class T>
class linkedStack: public stack<T>
{
public:
linkedStack(int initialCapacity = 10)
{
stackTop = NULL;
stackSize = 0;
}
~linkedStack();
bool empty() const
{
return stackSize == 0;
}
int size() const
{
return stackSize;
}
T& top()
{
if (stackSize == 0)
throw stackEmpty();
return stackTop->element;
}
void pop();
void push(const T& theElement)
{
stackTop = new chainNode<T>(theElement, stackTop);
stackSize++;
}
private:
chainNode<T>* stackTop; // 栈顶指针
int stackSize; // 栈中元素个数
};
template<class T>
linkedStack<T>::~linkedStack()
{// 析构函数
while (stackTop != NULL)
{// 删除栈顶节点
chainNode<T>* nextNode = stackTop->next;
delete stackTop;
stackTop = nextNode;
}
}
template<class T>
void linkedStack<T>::pop()
{// 删除栈顶节点
if (stackSize == 0)
throw stackEmpty();
chainNode<T>* nextNode = stackTop->next;
delete stackTop;
stackTop = nextNode;
stackSize--;
}
后续
下周开始学C++了,记录C++学习内容。数据结构跟着课上学完刷题就好了,暂时不记录了。这章栈的内容还不是很完善,还没开始刷题,等刷了题之后,理解更深入了,再补充完善。