[資料結構]棧之鏈式棧的類模板實現,鏈式模板
棧的抽象基類的實現:(不用抽象基類也是可以的,為了使用虛函數方便)
#ifndef STACK#define STACK//棧的抽象基類template<class T>class Stack{public: Stack(){} ~Stack(){} virtual void Push(const T& x)=0; virtual bool Pop(T& x)=0; virtual bool getTop(T& x)const=0; virtual bool IsEmpty()const=0; virtual bool IsFull()const=0; virtual int getSize()const=0;};#endif
鏈式棧模板類的具體實現:(覆蓋了抽象基類中的所有純虛函數,並增加了一些成員)
/////////////////////////#include"Stack.h"#include <iostream>#include <cstdlib>#include <cassert>using namespace std;template<class T> struct LinkNode //鏈表節點類 { T data; LinkNode<T>* link; LinkNode(LinkNode<T>* ptr=NULL):link(ptr){} LinkNode(const T& item,LinkNode<T>* ptr=NULL):data(item),link(ptr){} };template<class T>class LinkedStack:public Stack<T>{public: LinkedStack():top(NULL){} LinkedStack(const LinkedStack<T>& rhs); LinkedStack<T>& operator=(const LinkedStack<T>& rhs); ~LinkedStack(){makeEmpty();} void Push(const T& x); bool Pop(T& x); bool getTop(T& x)const; bool IsEmpty()const{return top==NULL?true:false;} bool IsFull()const{return false;}//無意義,不可能滿 int getSize()const; void makeEmpty(); friend ostream& operator<< <T>(ostream& out,LinkedStack<T>& rhs);//加<T>private: LinkNode<T>* top;};template<class T>void LinkedStack<T>::makeEmpty(){ LinkNode<T>* p=NULL; while(top!=NULL){ p=top; top=top->link; delete p; }}template<class T>void LinkedStack<T>::Push(const T& x){ top=new LinkNode<T>(x,top); assert(top!=NULL);}template<class T>bool LinkedStack<T>::Pop(T& x){ if(IsEmpty()) return false; LinkNode<T>* p=top; top=top->link; x=p->data; delete p; return true;}template<class T>bool LinkedStack<T>::getTop(T& x)const{ if(IsEmpty()) return false; x=top->data; return true;}template<class T>int LinkedStack<T>::getSize()const{ int k=0; LinkNode<T>* p=top; while(p!=NULL){ ++k; p=p->link; } return k;}template<class T>ostream& operator<<(ostream& out,LinkedStack<T>& rhs)//不加<T>{ out<<"elements nums: "<<rhs.getSize()<<endl; LinkNode<T>* p=rhs.top; out<<"elements is: "; while(p!=NULL){ out<<p->data<<" "; p=p->link; } out<<endl; return out;}template<class T>LinkedStack<T>::LinkedStack(const LinkedStack<T>& rhs){ LinkNode<T>* src=rhs.top; LinkNode<T>* dest=NULL; LinkNode<T>* newNode=NULL; while(src!=NULL){ newNode=new LinkNode<T>(src->data); if(dest==NULL){ dest=newNode; top=dest; }else{ dest->link=newNode; dest=newNode; } src=src->link; }}template<class T>LinkedStack<T>& LinkedStack<T>::operator=(const LinkedStack<T>& rhs)//copy賦值本質為:析構+copy建構函式{ if(top!=NULL)//先析構,釋放資源 makeEmpty(); LinkNode<T>* src=rhs.top;//copy構造 LinkNode<T>* dest=NULL; LinkNode<T>* newNode=NULL; while(src!=NULL){ newNode=new LinkNode<T>(src->data); if(dest==NULL){ dest=newNode; top=dest; }else{ dest->link=newNode; dest=newNode; } src=src->link; } return *this;}
類的測試代碼如下:
int main(int argc, char* argv[]){ LinkedStack<int> s; int a=1,b=2,c=3,d=4,e=5; s.Push(a); s.Push(b); s.Push(c); s.Push(d); s.Push(e); cout<<s; s.Pop(e); cout<<s; cout<<std::boolalpha;//控制顯式的bool值的顯式 cout<<"IsEmpty(): "<<s.IsEmpty()<<endl; cout<<"IsFull(): "<<s.IsFull()<<endl; cout<<std::noboolalpha; s.getTop(e); cout<<"getTop(): "<<e<<endl; s.makeEmpty(); cout<<s; s.Push(a); s.Push(b); s.Push(c); cout<<s; LinkedStack<int> s1(s),s2; cout<<s1; s2=s1; cout<<s2; system("pause"); return 0;}
測試結果如下:
elements nums: 5elements is: 5 4 3 2 1elements nums: 4elements is: 4 3 2 1IsEmpty(): falseIsFull(): falsegetTop(): 4elements nums: 0elements is:elements nums: 3elements is: 3 2 1elements nums: 3elements is: 3 2 1elements nums: 3elements is: 3 2 1請按任意鍵繼續. . .
注意事項:
1.在模板類的友元函數的實現與聲明時:聲明的時間要加額外的參數<T>,在實現的時間時不加的。
2. 實現中採用的是無附加頭結點的單鏈表,所以要注意拷貝時,鏈表要區分是否是空鏈表或者是第一次建立鏈表的情況。
3.鏈式棧的棧頂在鏈表的頭部,新節點的插入和刪除都是在棧頂進行的,是對棧頂元素的操作。
4.鏈表實現的棧是不可能滿的,所以總是返回false
5.採用cout<<std::boolaapha與cout<<std::noboolaapha可顯式的控制布爾值的顯式方式。