栈:数据处理的方式是:FILO (先进后出的方式)
数组栈:
//ADT:抽象数据类型
#include <iostream>
using namespace std;
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() = 0;//出栈
virtual void push(const T& theEelemnt) = 0;//出栈
};
template <class T>
class arrayStack :public stack<T>//stack<T> 第一容易犯错的地方
{
public:
//构造函数+拷贝构造函数
arrayStack(int initialCapacity = 1);
~arrayStack(){ delete[] stack; }
//判断是否为空
bool empty() const{ return stackTop == -1; }
int size()const{ return stackTop + 1; }
T& top()
{
if (stackTop == -1)
{
cout << "栈为空" << endl;
exit(0);
}
return stack[stackTop];
}//引用是对象本身,而不是对象的拷贝本。获取栈顶元素
void pop()//出栈
{
if (stackTop == -1)
{
cout << "栈为空" << endl;
exit(0);
}
stack[stackTop--].~T();
}
void push(const T& theEelemnt);//出栈
private:
int stackTop;//栈顶标志
int arrayLength; //数组长度
T *stack; //数组:用指针表示
};
//数组可变化的就可以
template<class T>
void ChangeLength1D(T *&a, int oldLength, int newLength)
{
if (newLength < 0)
{
cout << "重新分配空间" << endl;
exit(0);
}
T *temp = new T[newLength];
int number = oldLength>newLength ? oldLength : newLength;
//copy :源目的起始位置,源目的的终止 新内存
copy(a, a + number, temp);//STL用的比较多
a = temp;
}
template <class T>
arrayStack<T>::arrayStack(int initialCapacity = 1)
{
if (initialCapacity < 1)
cout << "容量必须大于0" << endl;
//构造函数---->初始化参数
arrayLength = initialCapacity;
stack = new T[arrayLength];
stackTop = -1;
}
template <class T>
void arrayStack<T>::push(const T& theElement)
{
if (stackTop == arrayLength - 1)
{
ChangeLength1D(stack, arrayLength, 2 * arrayLength);
arrayLength *= 2;
}
stack[++stackTop] = theElement;
}
int main()
{
arrayStack<int> mystack;//抽象类没有对象
mystack.push(1);
mystack.push(2);
mystack.push(3);
int i = 0;
cout << mystack.size() << endl;
while (i < 3)
{
cout << mystack.top() << " ";
mystack.pop();
i++;
}
return 0;
}
链表栈:
/*
FILO
栈结构
//STL stack
#include <stack>
#include <iostream>
using namespace std;
int main()
{
stack<int> mystack;
mystack.push(1);
mystack.push(2);
mystack.push(3);
int i = 0;
cout << mystack.size()<<endl;
while (i < 3)
{
cout << mystack.top()<<" ";
mystack.pop();
i++;
}
return 0;
}
*/
/*链表实现*/
//ADT
#include <iostream>
#include <string>
using namespace std;
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() = 0;//出栈
virtual void push(const T& theEelemnt) = 0;//出栈
};
//链表的结构体
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>
{
public:
//构造函数+析构函数
LinkedStack()
{
stackTop = NULL;
stackSize = 0;
}
~LinkedStack();
//纯虚基类继承的函数
bool empty() const{ return stackSize == 0; }
int size()const{ return stackSize; }
T& top()//引用是对象本身,而不是对象的拷贝本。获取栈顶元素
{
if (stackSize == 0)
{
cout << "栈为空" << endl;
exit(0);
}
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 (stackTop == NULL)
{
cout << "栈为空" << endl;
exit(0);
}
chainNode<T>* nextNode = stackTop->next;
delete stackTop;
stackTop = nextNode;
stackSize--;
}
int main()
{
LinkedStack <string> stack;
stack.push("饭");
stack.push("要吃");
stack.push("我");
int i = stack.size();
while (i--)
{
cout << stack.top() << " ";
stack.pop();
}
return 0;
}