Hello!Everybody and CSDN!So pleased to see all of you ------ my friends again!
距离我上一次发表博文貌似有一个月了快,不是自己懒惰(好像就是这样的。。。。。。),最近的事情太多了,工数,概率论期中考(到了大学才知道还要期中考!),还有英语四级的复习,话说看到去年12月咱院里考的那帮人个个500+,我心里那个冷汗流的。。。。。。不过去年考的都是英语A班,和卓越班的,实力摆在那(我四级也要上500!)。好不容易来了个五一,说什么也不能浪费!这个假期(才三天!!!算啥假期啊!)着手继续做接下来的数据结构作业。
上篇博文写了一个单向链表(说实话烂到不行,还放出来给别人看真心不好意思。。。),这次在上次的基础上设计一个链栈,
在贴代码之前,先回顾一下关于容器及容器适配器的概念及我对他们的一些理解。
容器:容器是一个用来封装数据及一些数据操作的类。
容器适配器:将一些基础类的容器转化为具有容器C性质的容器,如接下来的链栈。
简单地说,基本的容器类就是存储数据,并且封装了一些数据的基本操作,如插入,删除等等,而容器适配器则是在基本容器的基础上,利用基础容器的一些基础操作实现自己的操作,如链栈的出栈入栈就是利用链表的尾部插入,尾部删除(因为栈的顶即链表的尾)。
简单的回顾了一下基本的东西,接下来就是时间的部分了!下面贴代码。
#define EMPTY_ERROR "has been Empty!\n"
#define STACK "The stack "
#define LIST "The list "
#include<iostream>
#include<string>
using namespace std;
template<typename T>
struct Node
{
Node<T> *Rear_Node;
Node<T> *Front_Node;
T Number;
};
template<typename T>
class List_My
{
public:
List_My();
void insert(T Num);
void Delete();
void Search(T Num);
void Reverse();
bool Empty();
long Get_Size()
{ return this->Size; };
protected :
Node<T> *Front ;
Node<T> *Rear;
long Size;
};
//Constructing function
template<typename T>
List_My<T>::List_My()
{
this->Size = 0;
this->Front=NULL;
this->Rear =NULL;
}
//Insert operation
//just insert the num in the rear of the list
template<typename T>
void List_My<T>::insert(T Num)
{
Node<T> *Itr;
Itr = new Node<T>;
Itr->Number = Num;
Itr->Rear_Node = NULL;
if(this->Front!= NULL)
{
this->Rear->Rear_Node = Itr;
this->Rear = Itr;
}
else
{
this->Front = Itr;
this->Rear = Itr;
}
this->Size++;
Itr = this->Front;
while(Itr!=NULL) //You have to use the itraration here
{ //Because you may change the value of Front by accident
cout<<Itr->Number<<" ";
Itr = Itr->Rear_Node;
}
cout<<endl;
}
//Delete the number you want to delete in the list
//The function will delete the number which is in the rear
//of the list
//and just change the direction of the pointer---this->Rear
template<typename T>
void List_My<T>::Delete()
{
Node<T> *Itr;
if( this->Size > 1)
{
Itr = this->Front;
while( Itr->Rear_Node != this->Rear )
Itr = Itr->Rear_Node;
this->Rear = Itr;
Itr->Rear_Node = NULL;
this->Size--;
}
else if(this->Size==1)
{
this->Rear = NULL;
this->Front = NULL;
this->Size--;
}
else
{
cout<<LIST<<EMPTY_ERROR;
abort();
}
Itr = this->Front;
while(Itr!=NULL) //You have to use the itraration here
{ //Because you may change the value of Front by accident
cout<<Itr->Number<<" ";
Itr = Itr->Rear_Node;
}
cout<<endl;
};
template<typename T>
void List_My<T>::Search(T Num)
{
Node<T> *Itr = Front;
bool Judgement = false;
while(Itr != NULL)
{
if(Itr->Number == Num)
{
Judgement = true;
break;
}
Itr = Itr->Rear_Node;
}
if(Judgement)
cout<< "Success"<<endl;
else cout<< "Fail"<<endl;
};
template<typename T>
void List_My<T>::Reverse()
{
T Array[100];
int k=-1;
Node<T> *Itr = Front;
while( Itr!=NULL )
{
k++;
Array[k] = Itr->Number;
Itr = Itr->Rear_Node;
}
Itr = Front;
for(int i=k;i>=0;i--)
{
Itr->Number = Array[i];
Itr = Itr->Rear_Node;
}
Itr = Front;
while(Itr!=NULL) //You have to use the itraration here
{ //Because you may change the value of Front by accident
cout<<Itr->Number<<" ";
Itr = Itr->Rear_Node;
}
}
//Just to judge whether the list is empty
template<typename T>
bool List_My<T>::Empty()
{
if(Size == 0) return true;
else return false;
}
以上是基础的链表容器定义,接下来是栈。
#if 1
//The stack which bases on the List_My Template of Stack
template<typename T>
class Stack
{
public :
void Push(const T&); //define the fundamental operations of stack
void Pop();
bool IsEmpty();
long Size_Stack();
void Search();
protected:
List_My<T> Contain;
};
//To push a number into stack
template<typename T>
void Stack<T>::Push(const T& Temp)
{
this->Contain.insert(Temp);
}
//To pop the number in the top of the stack
template<typename T>
void Stack<T>::Pop()
{
if( !this->Contain.Empty())
this->Contain.Delete();
else cout<<STACK<<EMPTY_ERROR;
}
//If the satck is empty the function returns true
//else it returns false
template<typename T>
bool Stack<T>::IsEmpty()
{
return this->Contain.Empty();
}
//return the size of the stack
//by use the function Size_List() of Contain
template<typename T>
long Stack<T>::Size_Stack()
{
return this->Contain.Get_Size();
}
//If can find out the number in the stack
//output message "Success"
//or output "Failed"
template<typename T>
void Stack<T>::Search()
{
T Num_Temp;
cout<<"Pleaes input the number that you want to search \n";
cin>>Num_Temp;
this->Contain.Search(Num_Temp);
}
#endif
有木有好累,其实除去基础容器基础操作,适配器的操作是蛮轻松的,因为操作基础容器已经全部弄好了,只需要引用并且注意一些本身的问题就行了(个人看法,不喜希望多多指明原因!)
下面用主函数调试一些操作。
int main()
{
Stack<int> Stack_Ok;
Stack_Ok.Push(9);
Stack_Ok.Push(10);
Stack_Ok.Push(11);
for(int i=0;i<5;i++) //故意 Pop 5次,检查异常情况的处理
Stack_Ok.Pop();
Stack_Ok.Search();
cout<<"The size of the list:"<<Stack_Ok.Size_Stack()<<endl;
return 0;
}
经过上面的的调试会出现下面的情况:
好像是没啥问题的,(每次Pop 和 Push 操作之后都会输出整个栈,没有定义一个专门用来输出栈信息的函数,because of lazy ,lazy is the biggest enemy of success )。
OK!链栈的到此为止,回去再把顺序栈给做一做。Bye bye!