这两天学习了栈和队列,其实它们都是特殊的的线性表,只是对它的删除和插入操作做了限定。
栈是仅在表尾(栈顶)进行插入和删除操作,遵从先进后出的规则。它的一些应用,像是文档编辑器中的撤销操作,网页的后退操作,还有编辑器的对递归函数的处理,和四则运算表达式求值都用到了栈这样的数据结构。
这里分顺序和链式两种方式实现:
1.顺序存储结构:
缺陷是要先确定数组存储的大小,否则,还得扩容,比较麻烦。。
头文件,声明和定义放一块了
#ifndef STACK1_H #define STACK1_H #include <iostream> using namespace std; template<typename T> class Stack { public: Stack(int size); ~Stack(); void push(const T& node); //插入操作 void pop(); //弹出操作 T top(); //返回栈顶元素 int size()const; bool empty() const; void clear(); //此处是栈的顺序存储结构 private: T *data; int Top; //栈顶指针 int MAXSIZE; }; //空栈时top为-1,一个元素为0 template<typename T> Stack<T>::Stack(int size=100) :Top(-1),MAXSIZE(size) { data=new T[size]; } template<typename T> //对栈分配的空间调用析构函数 Stack<T>::~Stack() { clear(); delete [ ]data; } template<typename T> void Stack<T>:: clear() //对栈里面的元素调用元素对象的析构函数 { while(Top!=-1) data[Top--].~T(); } template<typename T> void Stack<T>::push(const T& value) { if(Top==MAXSIZE-1) { cerr<<"栈已经满"<<endl; return ; //可以像vector的函数reserve一样扩容,此处略 } data[++Top]= value; } template<typename T> T Stack<T>::top() { if (empty()) { cerr<<"Error, stack is empty!"; } return data[Top]; } template<typename T> void Stack<T>::pop() { if (empty()) { cerr<<"Error, stack is empty!"; return; } Top-- ; //或者data[Top--].~T();每弹出一个就析构一个元素 } template<typename T> bool Stack<T>::empty() const { return Top ==-1; } template<typename T> int Stack<T>::size()const { return Top+1; } #endif // STACK1_H
测试主程序:
#include <iostream> #include "Stack1.h" using namespace std; int main () { Stack<int> s(10); for(int i = 0; i < 10; ++i) { s.push(i); } for(int j = s.size()-1 ; j >= 0; --j) { cout<< "node: " << s.top() <<endl; s.pop(); } cout<<s.size(); return 0; }
2.链式存储结构:
头文件:
#ifndef STACK_H #define STACK_H #include <iostream> using namespace std; template<typename T> class Stack { public: Stack(); ~Stack(); void push(const T& node); //插入操作 void pop(); //弹出操作 T top(); //返回栈顶元素 int size()const; bool empty() const; void clear(); //此处是栈的链式存储结构 private: struct StackNode { T data; StackNode* next; StackNode(const T& Newdata, StackNode* nextNode) :data(Newdata),next(nextNode) { } }; StackNode * Top; //栈顶指针 int count; // 防止默认拷贝和默认赋值 Stack(const Stack& rhs); Stack& operator=(const Stack& rhs); }; template<typename T> Stack<T>::Stack() :Top(NULL),count(0){} template<typename T> Stack<T>::~Stack() { clear(); } template<typename T> void Stack<T>::push(const T& node) { Top = new StackNode(node,Top); count ++; } template<typename T> T Stack<T>::top() { if (empty()) { cerr<<"Error, stack is empty!"; } return Top->data; } template<typename T> void Stack<T>::pop() { if (empty()) { cerr<<"Error, stack is empty!"; } StackNode* stackTop= Top; Top = Top->next; delete stackTop; count--; } template<typename T> bool Stack<T>::empty() const { return Top ==NULL; } template<typename T> void Stack<T>::clear() { while (Top) { StackNode* stackTop = Top; Top = Top->next; delete stackTop; } count = 0; } template<typename T> int Stack<T>::size()const { return count; } #endif // STACK_H
主程序:
#include <iostream> #include "Stack.h" using namespace std; int main () { Stack<int> s; for(int i = 0; i < 10; ++i) { s.push(i); } for(int j = s.size()-1 ; j >= 0; --j) { cout<< "node: " << s.top() <<endl; s.pop(); } s.clear(); cout<<s.size(); return 0; }