顺序栈
前面的几篇是关于链表的,从今天开始我们把注意力转移到栈上面来。
栈是一个很重要又很常见的数据结构。用途非常广泛。比如后面将要提到的表达式计算进制转换等等都需要栈的配合。另外,栈还可以应用到函数调用等方面。
那么什么是栈呢?栈可以标准定义为只可以在表的末端进行插入和删除的线性表。那么容许插入和删除的一端叫做栈顶(top),而另一端叫做栈底。当栈中没有任何元素时,叫做空栈。
由于栈的特殊性。所以我们又把它称为后进先出的线性表。那这是为啥呢。看个图你就明白了;
栈的概念很简单,那么该如何用代码表示呢?
#ifndef STACK_H
#define STACK_H
#define maxsize 50
#include<iostream>
template<typename T> class Stack{
public:
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
我们可以这样进行定义:
上面的代码就是用c++语言进行的栈的类定义。通过代码我们对栈有了初步的了解了。
好了。现在我要深入研究一下栈了。回想链表,链表根据存储表示的不同,分为顺序表和链表,那么又因为栈是特殊的线性表。所以我们把栈也分为链栈和顺序栈,这篇主要介绍顺序栈。下一篇说链栈。
所谓顺序栈就是采用顺序表来进行存储表示的。我们可以用顺序表为顺序栈设计存储空间;为了简单,我用数组来表示。我们设栈数组的头指针为element。它的栈顶指针设为top,尽可以进行栈的操作了。详细情况代码;
#ifndef LITSTK_H
#define LITSTK_H
#include<iostream>
#include<assert.h>
using namespace std;
#define stackincreament 20
template<typename T> class Seqstack{
public:
Seqstack(int sz=50);
~Seqstack(){delete[]element;}
void Push(const T &x);
bool Pop(T& x);
bool gettop(T &x);
bool Isempty()const{return (top==-1)?true:false;}
bool Isfull()const{return (top==maxsize-1)?true:false;}
int getsize()const{return top+1;}
void makeempty(){top=-1;}
friend ostream &operator << (ostream &os,Seqstack<T>& s){
os<<"top="<<s.top<<endl;
for(int i=0;i<=s.top;i++)
{
os<<i<<":"<<s.element[i]<<endl;
}
return os;
}
private:
T *element;
int top;
int maxsize;
void overflowprocess();
};
#endif
template<typename T> Seqstack<T>::Seqstack(int sz):top(-1),maxsize(sz){
element=new T[maxsize];
assert(element!=NULL);
};
template<typename T> void Seqstack<T>::overflowprocess()
{
T *newarray=new T[maxsize+stackincreament];
assert(newarray);
for(int i=0;i<=top;i++)
{
newarray[i]=element[i];
}
maxsize=maxsize+stackincreament;
delete[]element;
element=newarray;
};
template<typename T> void Seqstack<T>::Push(const T &x)
{
if(Isfull()==true)
{
overflowprocess();
};
element[++top]=x;
};
template<typename T> bool Seqstack<T>::Pop(T &x)
{
if(Isempty()==true) return false;
x==element[top--];
return true;
};
template<typename T> bool Seqstack<T>::gettop(T &x)
{
if(Isempty()==true) return false;
x=element[top];
return true;
};
</pre><pre name="code" class="cpp">
说完顺序栈,再提下共享栈,怎样设计共享栈呢。我们要定义一个足够大的空间。让空间的两端为两个栈的栈底,我们用b【0】=-1和b【1】=maxsize来表示。让两个栈顶t【0】和t【1】向中间延伸,直到两个栈顶相遇。是发生溢出。如图:
那么每次进栈时,t[0]加一,t[1]j减一。相反在退栈时,t[0]减一,t[1]加1;
如何判断双栈的空满呢。先初始化t[0]=b[0]=-1;t[1]=b[1]=maxsize;栈满时,t[0]+1=t[1];注意,只有栈顶指针相遇才算满啊。栈空时,t[0]=b[0]或t[1]=b[1];然后栈指针退至栈底。
#include<iostream>
#include"LITSTK.h"
#include<stdlib.h>
using namespace std;
int main()
{
Seqstack<int> list(10);
int i,n,j=1;
cin>>n;
for(int p=0;p<n;p++)
{
cin>>i;
list.Push(i);}
list.Pop(j);
cout<<list<<endl;
system("pause");
}